uva1625 Color Length 线性动态规划

// uva1625 Color Length
// 这是好久之前在紫书(page 276)上看到的题目了
// 题目的意思是,给你两个长度分别为n和m的颜色序列(n,m<=5000)
// 都是由大写字母组成,要求按照顺序合并成同一个序列,即每次
// 可以把一个序列开头的颜色放在新序列的尾部
// 比如两个序列:GGBY 和 YRRGB至少有两种合并结果:
// GBYBRYRGB 和 YRRGGBBYB 对于每一种颜色c,跨度L(c)是最大位置和
// 最小位置之差,
// 问题是: 找一种合并的方式使得L(c)的总和最小。
//
// 首先,要换一种思维,每种颜色分别记录最小位置和最大位置,这个是不会有错的
// 之后,我们不是每种颜色单独去统计每次出现这种颜色时,他的最开始的位置,然
// 后再去加上此时的长度,而是所有颜色一起统计在第一个串i的位置和在第二个串j
// 的位置未结束但是已经开始的颜色的总数,因为最后统计的总的sigema(L)的时候
// 这些位置都是要算进去的
// 则:状态d(i,j)表示第一个串剩下i和第二个串剩下j时所得到的sigma(L)的最小值
// 则状态转移为:d(i,j) = min(d(i+1,j),d(i,j+1))+res(i,j);
// d(i+1,j)表示从第一个串拿走一个
// d(i,j+1)表示从第二个串拿走一个
// res(i,j)表示当前第一个串i,第二个串j位置时未结束但是已经开始的颜色的总数
//
//
//
// 感悟:
// 这道题真的看了很久很久,想了很久很久,看着书上的记录开始和结束的位置
// 我还能懂,之后计数的环节我就不太懂了,书上的代码我也没有看懂
// 目前只会这种状态的定义,而且细节部分还要多多的考究,会把紫书上的状态
// 再仔细的研习的,也望各位能够给予指点,小子实在是感激不尽
// 哎,继续练吧。。。
// 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ceil(a,b) (((a)+(b)-1)/(b))
#define endl '\n'
#define gcd __gcd
#define highBit(x) (1ULL<<(63-__builtin_clzll(x)))
#define popCount __builtin_popcountll
typedef long long ll;
using namespace std;
const int MOD = 1000000007;
const long double PI = acos(-1.L);

template inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; }
template inline T lowBit(const T& x) { return x&-x; }
template inline T maximize(T& a, const T& b) { return a=a inline T minimize(T& a, const T& b) { return a=ai-1&&start[k][1]>j-1)	continue;
				if (end[k][0]=0;i--)
		d[i][len2] = d[i+1][len2]+res[i][len2];
	for (int j=len2-1;j>=0;j--)
		d[len1][j] = d[len1][j+1]+res[len1][j];
	for (int i=len1-1;i>=0;i--)
		for (int j=len2-1;j>=0;j--)
			d[i][j] = min(d[i+1][j],d[i][j+1])+res[i][j];
	printf("%d\n",d[0][0]);
//	print();
}

int main() {
	int t;
	//freopen("G:\\Code\\1.txt","r",stdin);
	scanf("%d",&t);
	while(t--){
		init();
		solve();
	}
	return 0;
}

你可能感兴趣的:(dp)