sicily 1077(動態規劃)

2021-06-29 15:00:59 字數 1103 閱讀 5883

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個整數,表示序列中的數。輸...