USACO3.4.3 Raucous Rockers (rockers)

用动态规划求解

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;  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值