[Usaco2007 Dec]寶石手鐲
阿新 • • 發佈:2019-05-11
.com www. read 博客 輸入 ++ right 輸入格式 題目
題目描述
貝茜在珠寶店閑逛時,買到了一個中意的手鐲。很自然地,她想從她收集的 N(1 <= N <= 3,402)塊寶石中選出最好的那些鑲在手鐲上。對於第i塊寶石,它的重量為W_i(1 <= W_i <= 400),並且貝茜知道它在鑲上手鐲後能為自己增加的魅力值D_i(1 <= D_i <= 100)。由於貝茜只能忍受重量不超過M(1 <= M <= 12,880)的手鐲,她可能無法把所有喜歡的寶石都鑲上。 於是貝茜找到了你,告訴了你她所有寶石的屬性以及她能忍受的重量,希望你能幫她計算一下,按照最合理的方案鑲嵌寶石的話,她的魅力值最多能增加多少。
輸入格式
第1行: 2個用空格隔開的整數:N 和 M
第2..N+1行: 第i+1行為2個用空格隔開的整數:W_i、D_i,分別為第i塊寶石 的重量與能為貝茜增加的魅力值
輸出格式
第1行: 輸出1個整數,表示按照鑲嵌要求,貝茜最多能增加的魅力值
01背包的裸題。設dp[i]為使用了i個單位容量時的最大魅力值,c[i]為第i個物品的重量,v[i]為第i個物品的魅力值。那麽:
\[ dp[j]= \left\{\begin{array}{rcl} max(dp[j],dp[j-c[i]])+v[i])&j>=c[i]\ dp[j]&j<c[i] \end{array}\right. \]
如果你不知道這個轉移方程怎麽來的,而且你要學01背包......你可以看博主的這篇博客:
淺談01背包
#include<iostream> #include<cstring> #include<cstdio> #define maxn 3501 #define maxm 15001 using namespace std; int dp[maxm],c[maxn],v[maxn]; int n,m; inline int read(){ register int x(0),f(1); register char c(getchar()); while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); } while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int main(){ n=read(),m=read(); for(register int i=1;i<=n;i++) c[i]=read(),v[i]=read(); for(register int i=1;i<=n;i++){ for(register int j=m;j>=c[i];j--){ if(dp[j-c[i]]+v[i]>dp[j]) dp[j]=dp[j-c[i]]+v[i]; } } printf("%d\n",dp[m]); return 0; }
時間復雜度為:
\[ O(NM) \]
[Usaco2007 Dec]寶石手鐲