題目有點囉嗦,說白了給出一個上限s,n套郵票,每套有m張面值為ai的郵票,問不超過上限的前提下能組成最大的連續面值和(從1開始)。
dp[N]:組成面值為i的最小郵票數量+完全背包,更新幾個記錄值
#define N 1100int dp[N];//組成面值為i的最小數量int a[12][12];int main(){ int s; while(scanf("%d",&s) && s){ int i,j,k; int n; scanf("%d",&n); int ans = MIN; int index = 0; int num = MAX; int big = 0; for(i=1;i<=n;i++){ scanf("%d",&a[i][0]); int m = a[i][0]; for(j=1;j<=m;j++){ scanf("%d",&a[i][j]); } dp[0] = 0; int maxv = a[i][m]*s; for(j=1;j<=maxv;j++)dp[j] = (1<<30); for(j=1;j<=m;j++){ for(k=a[i][j];k<=maxv;k++){ dp[k] = min(dp[k],dp[k-a[i][j]] + 1); } } for(j=1;j<=maxv;j++){ if(dp[j]>s)break; } j--; if(j>ans){ ans = j; index = i; num = m; big = a[i][m]; } else if(j == ans){ if(m<num){ ans = j; index = i; num = m; big = a[i][m]; } else if(m == num){ if(a[i][m]<big){ ans = j; index = i; num = m; big = a[i][m]; } } } } printf("max coverage = %d :",ans); for(i=1;i<=num;i++){ printf(" %d",a[index][i]); } puts(""); } return 0;}