[USACO21FEB] Modern Art 3 G 题解

这么简单的区间dp我居然写挂了嘤嘤嘤

题解

主要是分为两种情况:

  • 定义 \(dp[i][j]\) 为区间 \([i,j]\) 内最少涂色次数,下面考虑转移

  • 首先考虑区间两边颜色相同的情况,我们只需要考虑将区间缩小一格时次数最少就可以了,即
    \(dp[i][j]=min \{dp[i+1][j],dp[i][j-1]\}\)

    注意:不可以写为 \(dp[i+1][j-1]+1\) ,这种情况没有考虑到 \(i+1\) 或 \(j-1\) 位置上也是颜色相同

  • 再考虑两侧颜色不同的情况。如果颜色不同,则需要枚举中间位置找出一个最优的位置即可。因为如果是将两侧颜色相同的包括了的话,一定已经算过了,在之前或之后的某处一定会算进去的

  • 处置设为正无穷,但 \(dp[i][i]\) 置为 \(0\)

#include <bits/stdc++.h>
using namespace std;
int n;
const int maxn=302;
int f[maxn][maxn],c[maxn];
int main()
{
//	freopen("paint.in","r",stdin);
//	freopen("paint.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	memset(f,0x3f,sizeof(f));
	for(int i=1;i<=n;i++)
		f[i][i]=1;
	for(int l=2;l<=n;l++)
	{
		for(int i=1;i+l-1<=n;i++)
		{
			int j=i+l-1;
			if(c[i]==c[j])
			{
				f[i][j]=min(f[i][j],min(f[i+1][j],f[i][j-1]));
			}
			else
			{
				for(int k=i;k<=j;k++)
				{
					f[i][j]=min(f[i][k-1]+f[k][j],f[i][j]);
				}
			}

		}
	}
	printf("%d",f[1][n]);
}
上一篇:Android性能调优之需要掌握Dalvik和ART的知识,flutter开源项目集合


下一篇:unity 2020打包apk出现Unable to locate player settings. bin/Data/settings.xml