the 3rd transformation is what makes this different from traditional 0/1 knapsack dp
state:
dp[i][j][k] - iterates songs with i while k minutes left in disk j
transformation:
if k>=s[i], means can add song i
dp[i+1][j][k]=max(dp[i][j][k], dp[i][j][k-s[i]]+1)
or k<s[i], means no more song can be added to disk j
dp[i+1][j][k]=dp[i][j][k]
fall through, we check if more songs can be added to a new disk if j>0, means there are still other disks to use
dp[i+1][j][k]=max(dp[i+1][j][k], dp[i][j-1][t-s[i]]+1)
/* UVas */ /*****************************************************************************/ int c, n, t, m, tmp; int d[800][100][100]; int s[800]; int main(void) { cin>>c; while (c--) { cin>>n>>t>>m; int p=0; scanf("%d", s+p++); for (int i=1; i<n; i++) { scanf(", %d", s+p++); } memset(d, 0, sizeof(d)); for (int i=0; i<n; i++) { for (int j=0; j<=m; j++) { for (int k=0; k<=t; k++) { if (k<s[i]) { d[i+1][j][k]=d[i][j][k]; } else { d[i+1][j][k]=max(d[i][j][k], d[i][j][k-s[i]]+1); } if (j>0) { d[i+1][j][k]=max(d[i+1][j][k], d[i][j-1][t-s[i]]+1); } } } } int r=0; for (int i=0; i<=n; i++) { r=max(r, d[i][m][0]); } cout<<r<<endl; if (c) { cout<<endl; } } return 0; } /*****************************************************************************/
No comments :
Post a Comment