P1282 多米诺骨牌 题解

Link

P1282 多米诺骨牌

Solve

看到题自然而然想到(DP),发现定义三维会爆空间,就考虑定义差值

定义(F[i][j])表示前(i)个多米诺骨牌,(sum{a_i}-sum{b_i})为j的最小次数

如果不翻,下一个状态的(j)(j+a[i]-b[i])不需要代价,如果翻了,下个状态是(j+b[i]-a[i])代价(1)

最后刷一个最优解就好了

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005,T=5000;
int N,a[maxn][2],F[maxn][T*2+5],ans,INF;
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
int main(){
	freopen("P1282.in","r",stdin);
	freopen("P1282.out","w",stdout);
	N=read();
	for(int i=1;i<=N;i++)a[i][0]=read(),a[i][1]=read();
	 memset(F,63,sizeof F);INF=F[0][0];
	F[0][T]=0;
	for(int i=1;i<=N;i++){
		for(int j=-T;j<=T;j++){
			F[i][j+T]=min(F[i-1][a[i][0]-a[i][1]+j+T],F[i-1][a[i][1]-a[i][0]+j+T]+1);
		}
	}
	for(int i=0;i<=T;i++){
		if(F[N][i+T]^INF||F[N][T-i]^INF){printf("%d
",min(F[N][T-i],F[N][i+T]));return 0;}
	} 
	return 0;
}
原文地址:https://www.cnblogs.com/martian148/p/13910930.html