1625: [Usaco2007 Dec]寶石手鐲
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1320 Solved: 933
[Submit][Status][Discuss]
Description
貝茜在珠寶店閒逛時,買到了一箇中意的手鐲。很自然地,她想從她收集的 N(1 <= N <= 3,402)塊寶石中選出最好的那些鑲在手鐲上。對於第i塊寶石,它的重量爲W_i(1 <= W_i <= 400),並且貝茜知道它在鑲上手鐲後能爲自己增加的魅力值D_i(1 <= D_i <= 100)。由於貝茜只能忍受重量不超過M(1 <= M <= 12,880)的手鐲,她可能無法把所有喜歡的寶石都鑲上。 於是貝茜找到了你,告訴了你她所有寶石的屬性以及她能忍受的重量,希望你能幫她計算一下,按照最合理的方案鑲嵌寶石的話,她的魅力值最多能增加多少。
Input
* 第1行: 2個用空格隔開的整數:N 和 M
* 第2..N+1行: 第i+1行爲2個用空格隔開的整數:W_i、D_i,分別爲第i塊寶石 的重量與能爲貝茜增加的魅力值
Output
* 第1行: 輸出1個整數,表示按照鑲嵌要求,貝茜最多能增加的魅力值
Sample Input
1 4
2 6
3 12
2 7
輸入說明:
貝茜收集了4塊寶石,她能忍受重量最大爲6的手鐲。
Sample Output
輸出說明:
貝茜把除了第二塊寶石的其餘所有寶石都鑲上手鐲,這樣她能增加
4+12+7=23的魅力值,並且所有寶石的重量爲1+2+3 <= 6,同樣符合要求。
題解:特別水的一道01揹包題,f[i]表示現體積爲i的最大價值爲多少,則f[j]=max(f[j],f[j-v[i]]+c[j]),此處v[i]表示第i個物品的體積。
詳情請看代碼:
#include<algorithm>
#include<cstdio>
using namespace std;
int n,m,ans,f[13001],v[3501],c[3501];
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
v[i]=read(),c[i]=read();
for(int i=1;i<=n;i++)
for(int j=m;j>=v[i];j--)
{
f[j]=max(f[j],f[j-v[i]]+c[i]);
ans=max(ans,f[j]);
}
printf("%d",ans);
return 0;
}