用动态规划求解
w[ i ][ j ]表示从i到j用一张光盘最多刻多少首歌,可用0-1背包求出
f [ i ][ j ]表示前j首歌用i个光盘最多刻多少首歌,状态转移方程:
f[ i ][ j ] = max{ f[ i ][ j ] , f[ i-1 ][ l ]+w[ l + 1][ j ] } (i - 1 <= l <= j - 1)
/*
ID:xsy97051
LANG:C++
TASK:rockers
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int w[30][30], f[30][30], ut[30], tmp[30];
int n, t, m, ans, cnt = 0;
int main()
{
freopen("rockers.in","r",stdin);
freopen("rockers.out","w",stdout);
cin>>n>>t>>m;
if(m>n) m=n;
for(int i=1;i<=n;i++)
cin>>ut[i];
memset(f,0,sizeof(f));
memset(w 0,sizeof(w));
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
memset(tmp,0,sizeof(tmp));
for(int k=i;k<=j;k++)
for(int v=t;v>=ut[k];v--)
tmp[v]=max(tmp[v],tmp[v-ut[k]]+1);
w[i][j] = tmp[t];
}
for(int j = 1; j <= n; j++) f[1][j] = w[1][j];
for(int i=2;i<=m;i++)
for(int j=i;j<=n;j++)
for(int k =i-1;k<j;k++)
f[i][j]=max(f[i][j], f[i-1][k]+w[k+1][j]);
cout<<f[m][n]<<endl;
return 0;
}