做题记录整理dp2 P1282. 多米诺骨牌(2022/9/20)

P1282. 多米诺骨牌

我们可以把每张骨牌的差值塞进dp的维度了,就变成dpi,j表示前i块骨牌的差值为j的最小旋转次数

就可以有递推方程

dp[i,j]=max(dp[i-1,j-(a[i]-b[i])],dp[i-1,j+(a[i]+b[i])]+1)

我们可以发现第二个维度会出现负数的情况,所以我们可以选择将数据的值域进行整体平移,从[-6000,6000]变成[0,12000]

这题算是一个剑走偏锋的dp类型了(还有一个整体平移的奇怪方法)

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int dp[1005][13001],n,m,a[500005],b[500005];
int main()
{
	cin>>n;
	for1(i,1,n)
	{
		scanf("%d%d",&a[i],&b[i]);
	}
	for1(i,0,n)
	for1(j,0,12001)
	dp[i][j]=1e8;
	dp[0][6000]=0;
	for1(i,1,n)
	{
		for1(j,-6000,6000)
		{
			int cha=a[i]-b[i];
		    dp[i][j+6000]=min(dp[i-1][j-cha+6000],dp[i-1][j+cha+6000]+1);
		}
	}
	int ans=1e8;
	for1(i,0,6000)
	{
			ans=min(dp[n][i+6000],dp[n][6000-i]);
			if(ans!=1e8)
			{
			
			cout<<ans<<endl;
			break;
		}
	}
	return 0;
}
posted @ 2022-09-20 15:49  yyx525jia  阅读(29)  评论(0)    收藏  举报