1. 程式人生 > >HDU 2159 FATE【二維揹包+完全揹包】

HDU 2159 FATE【二維揹包+完全揹包】

source:

題意:現在玩遊戲欲升級,升級需要經驗值n,殺怪可以賺經驗值,但是會扣忍耐度,遊戲中有k種怪,數目都無限多。現在玩家還有m點忍耐度,問能否在最多殺s個怪的情況下升級,若能則輸出剩餘的最大忍耐度。

思路:

1、此題有兩個約束,一個是忍耐度,一個是最多殺的怪物數。抽象來說意味著對於每件物品,具有兩種不同的費用。此即為二維揹包的模型!而二維費用揹包模型最常見的形式便是:物品總個數有上限限制,如此題的最多殺s個怪。而關於二維揹包的處理,無非是增加一個狀態維度即可,轉移方程類比著選或不選第i個物品的思路寫出即可。

2、此題怪物數目無限多,也即這是個完全揹包問題。關於完全揹包問題,存在O(N*V)時間複雜度的演算法(N為物品總數,V為揹包容量), 實現方式即為

                f[i,j]=max(f[i-1,j],f[i,j-v[i]]+w[i])  其中迴圈變數i遍歷物品種類,j正向遍歷0~V

注意遞推式與01揹包有些許不同:

     (1)max的第二項是f[i,...],是i

     (2)j在01揹包時是逆序迴圈的,如今變成了順序迴圈。

這樣的目的是,該子結果就是已經考慮過重複選第i項的結果了!另外這個i和j如果需要是可以交換迴圈順序的。

當然依然可以空間優化,去除物品種類那一維。而值得注意的是此題需要算的是如果可以升級需輸出能剩餘的最大忍耐度,故迴圈時可以將忍耐度那一維放在最外層迴圈,找到滿足條件的break輸出即可,爾後是怪物種類和怪物個數放在裡層迴圈,程式碼如下:

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

int w[105],v[105];//w為經驗(價值),v為忍耐度(容量1,而殺怪總數為容量2)
int dp[105][105];  //空間優化後的 忍耐度最多為v時,殺怪數為u時的最大經驗值

int main()
{
    int n,m,k,s;
    while(~scanf("%d%d%d%d",&n,&m,&k,&s))
    {
        for(int i=0;i<k;i++) scanf("%d%d",&w[i],&v[i]);
        memset(dp,0,sizeof(dp));
        int flag=1;
        for(int vv=0;vv<=m;vv++)   //此題是完全揹包,故正向迴圈;且與i交換了迴圈位置
        {
            for(int i=0;i<k;i++)
                for(int u=1;u<=s;u++) //此題是完全揹包,故正向迴圈
                if(vv>=v[i]) dp[vv][u]=max(dp[vv][u],dp[vv-v[i]][u-1]+w[i]);
            if(dp[vv][s]>=n)
            {
                printf("%d\n",m-vv);
                flag=0;
                break;
            }
        }
        if(flag) printf("-1\n");
    }
    return 0;
}


相關推薦

HDU 2159 FATE揹包+完全揹包

source: 題意:現在玩遊戲欲升級,升級需要經驗值n,殺怪可以賺經驗值,但是會扣忍耐度,遊戲中有k種怪,數目都無限多。現在玩家還有m點忍耐度,問能否在最多殺s個怪的情況下升級,若能則輸出剩餘

hdu 2159 FATE完全揹包

思路:觀察題目,有兩個約束條件,要在耐心的範圍內,而且不能超過殺怪數;所以簡單的一維揹包問題解決不了。要用二維的完全揹包來做; 二維完全揹包就是在有兩個代價c1,c2的時候,求在這種狀態下的最大收益;

HDU2159 FATE費用揹包+完全揹包

FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19336  &

HDU - 2159 FATE(有限制的01揹包

題目連結 01揹包問題,求m忍耐度最多能得到多少經驗,只是有一個殺怪數量的限制; #include <iostream> #include <cstring> #include <algorithm> using namespace std; int

碼QRious 介紹

二維碼又稱QR Code,QR全稱Quick Response,是一個近幾年來移動裝置上超流行的一種編碼方式,它比傳統的Bar Code條形碼能存更多的資訊,也能表示更多的資料型別。   二維條碼/二維碼(2-dimensional bar code)是用某種特定的幾何圖形按一定規律在平面(二維

D - FATE HDU-2159 FATE 背包

text panel ret sub lin printf print %d tdi D - FATE Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Sub

HDU 2159 FATE(有選擇物品總個數限制的完全揹包,經典!!)

FATE Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit

HDU 5517 樹狀數組///三偏序問題

void blog scan memset 集合 while ++ struct name 題目鏈接:【http://acm.split.hdu.edu.cn/showproblem.php?pid=5517】 題意:定義multi_set A<a , d>,B

Check Corners HDU - 2888線段樹

題目連結   很多人寫這道題都用的是二維RMQ,但是,我覺得這道題可以鍛鍊一下我二維線段樹的思維,但是,無獨有偶,這道題會卡一些二維線段樹的模板,一開始我想也沒想,直接敲了剛學的線段樹,然後不停的RE,後來改了下,換成單點更新與區間更新二維線段樹,還是不行TLE了,於是,就開始想,

Mosaic HDU - 4819線段樹

題目連結   這道題難就只是難在題目難讀,題意讀懂後就是一道普通的二維線段樹更新查詢問題。   題意:給你一個N*N的矩陣,並且已經建立了初始值,然後給你個點以及L,很多人不解其義,其實就是給你個點,然後查的是以(x, y)為基礎的點,在以左上角(x-L/2, y-L

Luck and Love HDU - 1823線段樹

題目連結   最近敲了些二維線段樹,這也是我題單裡的一道題,無非多出來的操作就是對區間端點的處理問題,給出的是浮點數,不如就把他向取整咯,一開始取整的時候總是會遇到些問題就是總是取不到恰好,會少位,怎麼辦呢?於是我這裡學到了個騷操作:(int)(x*10. + efs);其中,ef

費用的01揹包 HDU3496 HDU2184

HDU3496     已空間優化     疑惑點在 dp[時間][看電影數量]的初始化問題上面     dp[0][0]=0。。。。是吧     dp[0][i]=-inf,,,,,,,這個-inf一

HDU 2602 動態規劃+陣列、一陣列兩解法(01揹包

這道題就是簡單用二維陣列解決的時候,就是簡單的動態規劃,但是坑就坑在可能出現體積為0但是價值不為0的例子 一:二維陣列 下面是錯誤的程式碼 #include <iostream> #include <cstring> #include <

揹包問題進階優雅總結費用+分組+有依賴

目錄 作者有話說 小結 小結 分析 作者有話說 本篇博文中的各類陣列都從1開始 題目裡好像混進去了什麼奇怪的東西 二維費用的揹包問題 二維費用的揹包問題是指:對於每件物品,具有兩種不同的費用,選擇這件物品必須同時付出這兩種費用

POJ1195 Mobile phones 樹狀數組

chan mono ins written writing ram cor data- amp Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1428

樹狀數組See you~

get iostream closed href typedef 線段樹 比較 space 線段 https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F 【題意】 給定一個矩陣,每個格子的初始值為1。現在可以

hdu-1892 See you~---樹狀數組運用

sstream int d+ string \n pri scan HA else 題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=1892 題目大意: 題目大意:有很多方格,每個方格對應的坐標為(I,J),剛開始時每個格子裏

BZOJ4785 [Zjoi2017]樹狀數組 線段樹 + 標記永久化

結合 題解 php 數組 air line pri www ostream 題目鏈接 BZOJ4785 題解 肝了一個下午QAQ沒寫過二維線段樹還是很難受 首先題目中的樹狀數組實際維護的是後綴和,這一點憑分析或經驗或手模觀察可以得出 在\(\mod 2\)意義下,我們實際求

BZOJ1513 [POI2006]Tet-Tetris 3D 線段樹

get mem HR void 修改 mod 3D 理解 fine 題目鏈接 BZOJ1513 題解 真正地理解了一波線段樹標記永久化的姿勢 每個節點維護兩個值\(v\)和\(tag\) \(v\)代表兒子中的最值 \(tag\)代表未下傳的最值 顯然節點的區間大於等於\(

Oracle表管理:約束

value light 成功 字段 註意 ont sed 刪除外鍵 img 1、簡單的表創建和字段類型最簡單的方式去創建表(沒有添加主鍵之類的約束條件)【Oracle的字段類型】number:數值類型--整數類型:number(a) 總長度a--小數類型:number(a,