Codeforces 1221D Make The Fence great again 动规

题目链接:https://www.luogu.org/problem/CF1221D

题意:一个长为n的序列,我们可以花费b_i使得第i个数加1,要使任意相邻两个不相等的最小花费为多少

分析:一眼动规

首先,我们可以判断对任意一个数,我们对其的改变只能为+0,+1,+2

dp[i][j]表示前i个数已经符合要求,且第i个数加了0的最小花费

最后,动规时要记得特判a[i-1]+k!=a[i]+j,来保证修改后两者不会相等

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+7;
const int N=1e3+7;
const int inf=0x3f3f3f3f;
const ll INF=1e18+7;
int a[maxn],b[maxn];
ll dp[maxn][3];
int main(){
    int q;scanf("%d",&q);
    while(q--){
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]),dp[i][0]=INF,dp[i][1]=INF,dp[i][2]=INF;
        dp[0][0]=0;
        for(int i=1;i<=n;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    if(a[i-1]+k!=a[i]+j)//保证这相邻的两者经过操作后不会相等
                        dp[i][j]=min(dp[i][j],dp[i-1][k]+1ll*b[i]*j);
        ll ans=INF;
        for(int i=0;i<3;i++)ans=min(ans,dp[n][i]);
        printf("%I64d\n",ans); 
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qingjiuling/p/11574509.html