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+输出路径)