【题解】[Codeforces 1221D] Make The Fence Great Again【DP】

题目链接

题意

今有一个数列 \(a\),若其无相同数字相邻,则它是伟大的。你可以花费 \(b_i\) 的代价使 \(a_i\gets a_i+1\),可以多次操作。问至少花费多少代价来 Make 这个数列 Great Again 让数列是伟大的。多组询问。\(N\leq 3\times 10^5\)

题解

(正在尝试找出自己适合刷 CF 什么难度的题,感觉这道还是太简单了(?))

观察得,每个位置至多被加 \(2\) 次。故设 \(f[i,j]\) 代表前 \(i\) 个位置符合要求,且第 \(i\) 个位置加了 \(j\) 次的最少代价。

#include<bits/stdc++.h>
using namespace std;
int getint(){
	int ans=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		ans=ans*10+c-'0';
		c=getchar();
	}
	return ans*f;
}
const int N=3e5+10;
#define ll long long 
ll f[N][3];
int a[N],b[N];
int main(){
	int T=getint();
	while(T --> 0){
		int n=getint();
		for(int i=1;i<=n;i++)a[i]=getint(),b[i]=getint();
		memset(f,0x3f,sizeof(ll)*(n+2)*3);
		f[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]+j!=a[i-1]+k){
						f[i][j]=min(f[i][j],f[i-1][k]+j*1ll*b[i]);
					}
				}
			}
		}
		printf("%I64d\n",min({f[n][0],f[n][1],f[n][2]}));
	}
	return 0;
}
posted @ 2020-11-02 09:31  破壁人五号  阅读(82)  评论(0编辑  收藏  举报