sicily 1077
題目分析:一看便知道,這是乙個多重揹包問題,但是關鍵不在這裡,而在資料量——好大,於是我們需要一種優化——多重揹包轉0-1揹包
解題思路:
首先我們考慮第 i 種物品,如果它有num[i]個,那麼我們可以把它當成num[i]個物品來看,這樣就轉成了0-1揹包問題。但是,這樣沒有用啊,時間複雜度並沒有得到改善,怎麼辦呢?我們是在用計算機解決問題,那麼就永遠離不開二進位制,試一下用二進位制的思想,來劃分這num[i]個物品。
舉個例子,加入第 i 個物品有13個,那麼我們就有13種選擇手段(全部物品一樣,只有個數差別)。如果我們把這13個物品如此劃分:1、2、4、6,那麼是不是所有選擇的可能性都可以由這幾個數湊出來?答案是yes,自己試一下就懂了。其實這跟二進位制表示數字的思想是一樣的,這樣我們就可以把物品分成大約log( num[i] )個,那麼計算每種物品的複雜度就從o( num[i]*v )降到了o( log( num[i] )*v ),簡直奇妙!
**:
#include
#include
#include
#include
using namespace std;
int n,v,num[15],v[15],dp[100005];
int main()
memset(dp,0,sizeof(dp));
dp[0]=0;
for(int i=0;iint len=num[i],k=1;
while(len>=k)
for(int j=v;j>=len*v[i];j--)
dp[j]=max(dp[j],dp[j-len*v[i]]+len*v[i]);
if(dp[v]==v)
break;
}printf("%d\n",dp[v]);
}return
0;}
總結:
1、永遠記住二分的思想!
2、多重揹包的乙個簡單但卻有效的優化!
sicily 1176 (動態規劃)
題目連線 sicily 1176 解題思路 題目看上去像是一道博弈的題,又像是一道區間型dp的題目 矩陣取數 而它跟矩陣取數的區別就是他是兩個人在取數,所以每次對乙個區間,我們應分兩種情況考慮 第乙個人取左邊的數和取右邊的數,而在分別考慮這兩種情況時,我們又要根據貪心法則來獲取上乙個取數的區間。狀態...
動態規劃 sicily1221
解題思路 題目有個地方,我理解錯了,導致wa很多次,問題是當你擦除a i 時,你要將它對應的b i 去減剩餘的序列,之前一直以為第i輪就減去b i orz。簡單的動態,dp i 表示去到第i輪時的最大擦出和。按照我們直觀的思路,肯定是最大消費的 也就是b i 比較大的 應該先拿掉,因此我們先按照co...
九度OJ 1077 最大序列和 動態規劃
題目描述 給出乙個整數序列s,其中有n個數,定義其中乙個非空連續子串行t中所有數的和為t的 序列和 對於s的所有非空連續子串行t,求最大的序列和。變數條件 n為正整數,n 1000000,結果序列和在範圍 2 63,2 63 1 以內。輸入 第一行為乙個正整數n,第二行為n個整數,表示序列中的數。輸...