标签:
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 33998 | Accepted: 11554 |
Description
Input
Output
Sample Input
3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0
Sample Output
8 4
Source
有n种不同面值的硬币,面值各为A1,A2,A3。。AN,数量各为C1,C2,C3,,,,,CN。给定数m,问这些硬币能组成小于等于m的数中的哪些数,输出这些数的数目。
其实这个vn算法的编码很简单,关键是如何证明这种贪心是正确的,这个比较复杂,,我还在理解中!!!!!!!!
---用单调队列优化的DP已超出了NOIP的范围,
#include<cstdio> #include<cstring> using namespace std; int n,m,ans,w[105],v[105],d[100005],s[100005]; int main() { while(scanf("%d%d",&n,&m)==2&&n&&m){ int i,j;ans=0; for(i=0;i<n;i++) scanf("%d",w+i); for(i=0;i<n;i++) scanf("%d",v+i); memset(d,0,sizeof(d)); for(d[i=0]=1;i<n;i++){ for(j=0;j<=m;j++) s[j]=0; for(j=w[i];j<=m;j++) if(!d[j]&&d[j-w[i]]&&s[j-w[i]]<v[i]) d[j]=1,s[j]=s[j-w[i]]+1; } for(i=1;i<=m;i++) if(d[i]) ans++; printf("%d\n",ans); } return 0; }
#include<cstdio> int n,m,res; int use[100005],c[105],f[100005]; int main() { f[0]=1; while(scanf("%d%d",&n,&m)==2&&n&&m){ res=0; for(int i=1;i<=m;i++) f[i]=0; for(int i=0;i<n;i++) scanf("%d",&c[i]); for(int i=0,s;i<n;i++){ for(int j=0;j<=m;j++) use[j]=0; scanf("%d",&s); for(int j=c[i];j<=m;j++){ if(!f[j]&&f[j-c[i]]&&use[j-c[i]]<s){//贪心过程 use[j]=use[j-c[i]]+1; f[j]=1; res++; } } } printf("%d\n",res); } return 0; }
标签:
原文地址:http://www.cnblogs.com/shenben/p/5616973.html