[基础DP][CF189A]Cut Ribbon

CF-189A

题目大意:

可以将一条长为n的彩带剪成a, b, c三种长度,问最多可以剪成多少段。

题目分析:

可以考虑dp[x]表示长度为x的彩带最多可以剪成dp[x]段,那么dp[x] 的上一步,显然就是dp[x-a],dp[x-b],dp[x-c]这三个长度得来,显然找到这三个的最大值就可以了。关键在于初始值的设定,可以假定无法裁剪的数值为负无穷大,假定dp[0] = 0. 那么就可以很好的实现dp的递推了。

参考代码

#include 
using namespace std;
const int maxn = 4000+10;
const int INF = 9999999;
int dp[maxn];
 
int main(){
    int n;
    int v[3];
    cin >> n >> v[0] >> v[1] >> v[2];
    // sort: v[0]<=v[1]<=v[2]
    if(v[0]>v[1]) swap(v[0], v[1]);
    if(v[0]>v[2]) swap(v[0], v[2]);
    if(v[1]>v[2]) swap(v[1], v[2]);
    
    dp[0] = 0;
    for(int i=1; i<=n; i++){
        dp[i] = -INF;   // 表示无法凑够i 
        for(int j=0; j<3; j++)
            if(i>=v[j])
                dp[i] = max(dp[i], dp[i-v[j]] + 1);
    //  printf("dp[%d] = %d\n", i, dp[i]);
    }
    cout << dp[n];
    return 0;
} 

你可能感兴趣的:([基础DP][CF189A]Cut Ribbon)