原題傳送門html
這道題乍看有點難度,但其實就是個容量等於價格的揹包問題QAQ。ios
關於揹包問題,詳見個人另外一篇博文:【洛谷】採藥spa
此題只要把上一題的代碼稍做作些修改便可~code
設dp[i][j]爲前i個物體裝入容量爲j的揹包的最大價值,w[i],v[i]分別爲第i個物品的重量和價格。htm
狀態轉移方程爲:blog
dp[i][j]=dp[i-1][j] (j<w[i]) dp[i][j]=max{dp[i-1][j],dp[i-1][j-w[i]]+v[i]} (j≥w[i])
水代碼開始~(逃~~~)get
//經典揹包,無需解釋 #include<iostream> #include<cstdio> #include<cmath> using namespace std; int T,M,w[31],v[31],dp[31][20001]; int main() { //初始化 for(int i=1;i<=M;i++) { dp[i][0]=0; } for(int i=1;i<=T;i++) { dp[0][i]=0; } //讀入 scanf("%d%d",&T,&M); for(int i=1;i<=M;i++) { scanf("%d",&w[i]); v[i]=w[i]; } //裝叉走起 for(int i=1;i<=M;i++) { for(int j=1;j<=T;j++) { if(j<w[i]) { dp[i][j]=dp[i-1][j]; } else { dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); } } } //輸出 printf("%d",T-dp[M][T]); return 0; }
此外還能夠把空間壓爲一維。io
//經典揹包,無需解釋 #include<iostream> #include<cstdio> #include<cmath> using namespace std; int T,M,w[31],v[31],dp[20001]; int main() { for(int i=1;i<=T;i++) { dp[i]=0; } scanf("%d%d",&T,&M); for(int i=1;i<=M;i++) { scanf("%d",&w[i]); v[i]=w[i]; } for(int i=1;i<=M;i++) { for(int j=T;j>=1;j--) { if(j>=w[i]) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } printf("%d",T-dp[T]); return 0; }