UOJ495 新年的促销(动态规划)
Posted sunshine-chen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ495 新年的促销(动态规划)相关的知识,希望对你有一定的参考价值。
首先考虑一下:如果我们知道要买(或送)哪几袋米,如何确保自己的钱够用?
显然应该买最便宜的几个,剩下的送。
所以我们可以枚举一个$p$,比$p$便宜的米用买的方式,比$p$贵的米用送的方式,不会遗漏最优解。把米按价格排序用背包就可以做到$O(n^2m)$。
#include<cstdio> #include<cstring> #include<algorithm> #define For(i,A,B) for(i=(A);i<=(B);++i) using namespace std; struct node{ int w,p; }a[305]; int f[2005][305],g[305][305],t[305],ans[2005]; inline bool cmp1(const node &a,const node &b){return a.p<b.p;} inline bool cmp2(int x,int y){return x>y;} inline void chkmax(int &a,int b){if(b>a)a=b;} int main(){ int n,m,x,y,i,j,k; scanf("%d%d%d%d",&n,&m,&x,&y); For(i,1,n)scanf("%d",&a[i].w); For(i,1,n)scanf("%d",&a[i].p); sort(a+1,a+n+1,cmp1); For(i,1,n){ For(j,1,n-i+1)t[j]=a[j+i-1].w; sort(t+1,t+n-i+2,cmp2); For(j,1,n-i+1)g[i][j]=g[i][j-1]+t[j]; } memset(f,~0x3f,sizeof(f)); For(i,0,m)f[i][0]=0; For(i,1,n) for(j=m;j>=a[i].p;--j) for(k=i;k;--k){ chkmax(f[j][k],f[j-a[i].p][k-1]+a[i].w); chkmax(ans[j],f[j][k]+g[i+1][min(k/x+k/y,n-i)]); } For(i,1,m)printf("%d ",ans[i]); return 0; }
以上是关于UOJ495 新年的促销(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章