[USACO1996Qualifying Round]Raucous Rockers录制唱片
题目链接:找不到orz 要数据测的找我..
题目大意:
题解:
DP。。啊
f[i][j][k]表示录制第i张唱片,录到第j首歌(不一定录进去了),已经花了k时间的答案的最大值
那么我们可以有两种转移方式:
1、新开一张专辑来录我现在这首歌,cnt=max(f[i-1][j-1][k]);这个是处理出上一张专辑搞到第j-1首歌的所有情况中答案最多的有多少。
2、接着上一次的来选择录不录歌max(f[i][j-1][k-t[i]]+1(录),f[i][j-1][k](不录))
所以总的方程式就是:f[t][j][k]=mymax(f[t][j][k],mymax(cnt,f[t][j-1][k-a[j]])+1);
ans取最大的f[i][j][k].要滚动
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> using namespace std; #define maxn 1100 int a[maxn],f[2][maxn][maxn]; int mymax(int x,int y){return (x>y)?x:y;} int main() { //freopen("rockers.in","r",stdin); //freopen("rockers.out","w",stdout); int n,c,m,i,j,k,t; scanf("%d%d%d",&n,&c,&m); for (i=1;i<=n;i++) scanf("%d",&a[i]); int ans=0;t=0; f[1][1][0]=0; for (i=1;i<=m;i++) { for (j=1;j<=n;j++) { int cnt=0; for(k=c;k>=0;k--) cnt=mymax(cnt,f[1-t][j-1][k]); for (k=0;k<=c;k++) f[t][j][k]=f[t][j-1][k]; for (k=c;k>=a[j];k--) { f[t][j][k]=mymax(f[t][j][k],mymax(cnt,f[t][j-1][k-a[j]])+1); ans=mymax(ans,f[t][j][k]); } } t=1-t; }printf("%d\n",ans); return 0; }