题意:给出一个上限硬币数量s,给出n套硬币价值,求一套硬币能用不大于s数量的硬币组成从1开始连续的区间价值,其中,如果其最大值相同,输出数量小的和价值小的。
思路:很明显的完全背包,纠结后面最大值相同时的情况没判断,WA好多次。
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #define inf 1000000 using namespace std; int a[20][20]; int dp[2005]; int num[20]; int n,ans,p,s,t,maxv; int main() { while(scanf("%d",&s)!=EOF,s) { scanf("%d",&n); ans=0;t=0; for(int i=0;i<n;i++) { scanf("%d",&num[i]); for(int j=0;j<num[i];j++) { scanf("%d",&a[i][j]); } } for(int i=0;i<n;i++) { maxv=s*a[i][num[i]-1]; for(int j=0;j<=maxv;j++) { dp[j]=inf; } dp[0]=0; for(int j=0;j<num[i];j++) { for(int k=a[i][j];k<=maxv;k++) { dp[k]=min(dp[k],dp[k-a[i][j]]+1); } } int temp=0; for(int j=0;j<=maxv;j++) { if(dp[j]>s) { temp=j-1; break; } if(j==maxv) temp=maxv; } if(temp>ans) { ans=temp; t=i; } else if(temp==ans) { if(num[i]<num[t]) { t=i; } else if(num[i]==num[t]) { if(a[i][num[i]-1]<a[t][num[t]-1]) t=i; } } } printf("max coverage = %d :",ans); for(int i=0;i<num[t];i++) { printf(" %d",a[t][i]); } printf(" "); } return 0; }