【刷题】【dp】地精的贸易
完全背包
难点:输出方案
wa点:m的范围在一次dp后,出现变化,导致re
#include<cstdio> #include<cstdlib> using namespace std; int m,n; const int N=103,M=1000003; int a[N],b[N]; int f[2][M];//完全背包(压成一维) int pre[2][M]; int ans[N]; int main() { //input scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); //dp_0 for(int i=1;i<=n;i++) { int val=b[i]-a[i];//卖出价-买入价 if(val<=0) continue; for(int j=a[i];j<=m;j++) if(f[0][j] < f[0][j-a[i]]+val ) { f[0][j]=f[0][j-a[i]]+val; pre[0][j]=i; } } int mm=m+f[0][m]; //dp_1 for(int i=1;i<=n;i++) { int val=a[i]-b[i];//卖出价-买入价 if(val<=0) continue; for(int j=b[i];j<=mm;j++) if(f[1][j] < f[1][j-b[i]]+val ) { f[1][j]=f[1][j-b[i]]+val; pre[1][j]=i; } } //find_way => get_excel int pos=m; while(pre[0][pos]) { ans[pre[0][pos]]++; pos-=a[pre[0][pos]]; } pos=mm; while(pre[1][pos]) { ans[pre[1][pos]]++; pos-=b[pre[1][pos]]; } //output printf("%d\n",f[0][m]+f[1][mm]); for(int i=1;i<=n;i++) { printf("Buy %d",ans[i]); if(ans[i] ) if(a[i]>b[i]) printf(" from Horde"); else printf(" from Alliance"); putchar('\n'); } return 0; }