1. 程式人生 > >[NOIP提高組]金明的預算方案

[NOIP提高組]金明的預算方案

占用 lose mes std cst 一次 problem 減少空間 color

題目鏈接

題目分析

首先這道題目是背包九講裏面第7講中的有依賴的背包(不過那篇我沒怎麽看懂),本題中我們可以把附件和主件看成一組,總共有4種情況。

1.選主件 不選附件

2.選主件 選附件1

3.選主件 選附件2

4.選主件 選附件1 和 選附件2

這四種情況,我們可以可以做一次01背包,選出主件這一組中這四種情況中的最大價值即可。

還有一個優化是 因為錢是10的倍數 可以除以10 減少空間占用

技術分享
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,V;
int
v[62],w[62],v1[62],w1[62],v2[62],w2[62]; int dp[5005]; int ans; int main(){ scanf("%d%d",&V,&m); V/=10; for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); x/=10; if(z){ if(!v1[z]){ v1[z]=x; w1[z]
=x*y; } else{ v2[z]=x; w2[z]=x*y; } } else{ v[i]=x; w[i]=y*x; n=i; } } for(int i=1;i<=n;i++) for(int j=V;j>=v[i];j--){ dp[j]
= max(dp[j],dp[j-v[i]]+w[i]); if(j-v[i]-v1[i]>=0) dp[j] = max(dp[j],dp[j-v[i]-v1[i]]+w[i]+w1[i]); if(j-v[i]-v1[i]-v2[i]>=0) dp[j] = max(dp[j],dp[j-v[i]-v1[i]-v2[i]]+w[i]+w1[i]+w2[i]); if(j-v[i]-v2[i]>=0) dp[j] = max(dp[j],dp[j-v[i]-v2[i]]+w[i]+w2[i]); } printf("%d",dp[V]*10); return 0; }
代碼實現

[NOIP提高組]金明的預算方案