题目有点啰嗦,说白了给出一个上限s,n套邮票,每套有m张面值为ai的邮票,问不超过上限的前提下能组成最大的连续面值和(从1开始)。
dp[N]:组成面值为i的最小邮票数量+完全背包,更新几个记录值
#define N 1100
int 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;
}