CodeForces 704B Ant Man

CodeForces 704B Ant Man

https://codeforces.com/problemset/problem/704/B

Snipaste_2020-06-28_20-05-54.png

Tutorial

https://blog.sengxian.com/solutions/cf-704b

发现 (i) 的贡献只与 (i,j) 的相对大小有关, (j) 的贡献亦然.

我们要求就是一条从 (s)(e) 的链,想要用DP来解决这个问题.

那么很容易想到,DP状态和当前联通块链的个数有关.

(3) 种链

  • 包含 (s) 的链
  • 包含 (t) 的链
  • 其他链

(dp(i,j,u,v)) 表示 ([1,i]) 这些点中,3,1,2种链的个数为 (j,u,v) 时的最小值,转移就是向这个图中加入 (i+1) 这个点的位置

  • 单独成链
  • 一个链前方
  • 一个链后方
  • 连接两个链

(i+1=s,e) 时特殊处理一下即可.

Code

#include <cstdio>
#include <cstring>
#include <iostream>
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
inline char nc() {
//	return getchar();
	static char buf[100000],*l=buf,*r=buf;
	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
}
template<class T> void read(T &x) {
	x=0; int f=1,ch=nc();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
	x*=f;
}
template<class T> inline bool Cmin(T &x,T y) {return x>y?x=y,1:0;}
typedef long long ll;
const ll INF=1e18;
const int maxn=5000+5;
int n,s,e,x[maxn],a[maxn],b[maxn],c[maxn],d[maxn];
ll f[2][maxn][2][2];
int main() {
	read(n),read(s),read(e);
	for(int i=1;i<=n;++i) read(x[i]);
	for(int i=1;i<=n;++i) read(a[i]),a[i]+=x[i];
	for(int i=1;i<=n;++i) read(b[i]),b[i]-=x[i];
	for(int i=1;i<=n;++i) read(c[i]),c[i]+=x[i];
	for(int i=1;i<=n;++i) read(d[i]),d[i]-=x[i];
	int cur=0;
	for(int u=0;u<2;++u) for(int v=0;v<2;++v) f[cur][0][u][v]=INF;
	f[cur][0][0][0]=0;
	for(int i=1;i<=n;++i) {
		cur^=1;
		for(int j=0;j<=i;++j) for(int u=0;u<2;++u) for(int v=0;v<2;++v) f[cur][j][u][v]=INF;
		for(int j=0;j<i;++j) for(int u=0;u<2;++u) for(int v=0;v<2;++v) if(f[cur^1][j][u][v]!=INF) {
			if(i==s) {
				if(j) Cmin(f[cur][j-1][1][v],f[cur^1][j][u][v]+c[i]);
				Cmin(f[cur][j][1][v],f[cur^1][j][u][v]+d[i]);
				if(i==n) Cmin(f[cur][j][0][0],f[cur^1][j][u][v]+c[i]);
			}
			else if(i==e) {
				if(j) Cmin(f[cur][j-1][u][1],f[cur^1][j][u][v]+a[i]);
				Cmin(f[cur][j][u][1],f[cur^1][j][u][v]+b[i]);
				if(i==n) Cmin(f[cur][j][0][0],f[cur^1][j][u][v]+a[i]);
			}
			else {
				if(j||v) Cmin(f[cur][j][u][v],f[cur^1][j][u][v]+b[i]+c[i]);
				if(j||u) Cmin(f[cur][j][u][v],f[cur^1][j][u][v]+a[i]+d[i]);
				if(j>1||(j&&(u||v))) Cmin(f[cur][j-1][u][v],f[cur^1][j][u][v]+a[i]+c[i]);
				Cmin(f[cur][j+1][u][v],f[cur^1][j][u][v]+b[i]+d[i]);
				if(i==n) Cmin(f[cur][j][0][0],f[cur^1][j][u][v]+a[i]+c[i]);
			}
		}
	}
	printf("%lld
",f[cur][0][0][0]);
	return 0;
}
原文地址:https://www.cnblogs.com/ljzalc1022/p/13204842.html