[usaco3.1.5]stamps
dp思想,用num[1..n]来记录每个邮票的面值,然后f[i]表示i这个面值要用多少张邮票。转移过程:f[i]=min(f[i-num[j]]+1,f[i]),然后最后要输出i-1(因为退出条件是i不满足)。
/* ID:abc31261 LANG:C++ TASK:stamps */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int maxn=210,maxm=maxn*10000; int num[maxn],f[maxm]; int main() { int i,j,k,n,sum=0; freopen("stamps.in","r",stdin); freopen("stamps.out","w",stdout); scanf("%d%d",&k,&n); memset(f,0x7f,sizeof(f)); for (i=1;i<=n;i++) { scanf("%d",&num[i]); sum=max(sum,200*num[i]); } sort(num+1,num+n+1); f[0]=0; for (i=1;i<=sum;i++) if (f[i]>k) { for (j=1;j<=n;j++) { if (i<num[j])break; //因为这个优化,所以num数组要排序。 f[i]=min(f[i-num[j]]+1,f[i]); } if (f[i]>k)break; } printf("%d\n",i-1); return 0; }