Codeforces Round #493 (Div. 2) BCutting

Posted awcxv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #493 (Div. 2) BCutting相关的知识,希望对你有一定的参考价值。

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


在这里输入题意

【题解】


显然只有在前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) BCutting的主要内容,如果未能解决你的问题,请参考以下文章

Cutting Codeforces Round #493 (Div. 2)

Codeforces Round #493 (Div. 2) BCutting

Codeforces round 493 Convert to Ones

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Vasya and Basketball CodeForces - 493C