码迷,mamicode.com
首页 > 其他好文 > 详细

【Codeforces Round #493 (Div. 2) B】Cutting

时间:2018-09-30 21:53:26      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:line   cost   最小   ret   cout   def   include   cos   怎么   

【链接】 我是链接,点我呀:)
【题意】


在这里输入题意

【题解】


显然只有在前i个位置奇数偶数出现次数都相同的地方才能切。
(且不管前面怎么切,这里都能切的。
那么就相当于有n个物品,每个物品的代价是|a[i]-a[i-1]|,然后价值是1.
问你不超过B的代价的最大价值是多少。
这就转化成一个01背包模型了。
或者也可以这么写。
\(dp[i][j]表示前i个物品选择(切)了j个的最小花费\)
然后dp[i][j]=min(dp[i-1][j-1]+cost[i],dp[i-1][j]);//分别表示切第i个与不切第i个。
然后从大到小遍历一遍dp[n][i];输出最大的使得dp[n][i]<=B的i就可以了

【代码】

#include <bits/stdc++.h>

using namespace std;

const int N = 100;
const int INF = 1e8;

//dp[i][j] 前i个位置,cut了j次的最小花费
//dp[i][j] = min(dp[i-1][j-1]+cost[i],dp[i-1][j]);
int dp[N+10][N+10],n,B;
int pre[N+10][2],a[N+10],cost[N+10],cnt;

int main()
{
    #ifdef LOCAL_DEFINE
        freopen("rush.txt","r",stdin);
    #endif // LOCAL_DEFINE
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> n >> B;
    for (int i = 1;i <= n;i++) cin >> a[i];
    for (int i = 1;i <= n;i++){
        for (int j = 0;j < 2;j++) pre[i][j] = pre[i-1][j];
        pre[i][a[i]&1]++;
    }
    for (int i = 1;i <= n-1;i++)
        if (pre[i][0]==pre[i][1]){
            cost[++cnt] = abs(a[i+1]-a[i]);
        }
    n = cnt;
    for (int i = 0;i <= N;i++)
        for (int j = 0;j <= N;j++)
            dp[i][j] = INF;
    dp[0][0] = 0;
    for (int i = 1;i <= n;i++)
        for (int j = 0;j <= i;j++){
            dp[i][j] = dp[i-1][j];//no cut i
            if (j>0){
                dp[i][j] = min(dp[i][j],dp[i-1][j-1]+cost[i]);//cut i
            }
        }
    for (int j = n;j >= 0;j--){
        if (dp[n][j]<=B){
            cout<<j<<endl;
            return 0;
        }
    }
    return 0;
}

【Codeforces Round #493 (Div. 2) B】Cutting

标签:line   cost   最小   ret   cout   def   include   cos   怎么   

原文地址:https://www.cnblogs.com/AWCXV/p/9733338.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!