[每日N题] 3.31 Folding UVA - 1630 [动态规划]

Folding UVA - 1630

一看就是动态规划
如果 str1[i] == str2[j] d[i][j] = d[i+1][j+1]
否则 d[i][j] = min(d[i+1][j], d[i][j+1])
注意一定要用getline读入数据,用cin会wa

#include<iostream> 
#include<cstring>

using namespace std;

const int MAXN = 32;
const int INFINITE = 10000;

int d[MAXN][MAXN], len1, len2;
long long cnt[MAXN][MAXN]; // 统计数目要用long long类型 
string str1, str2; 

void init () {
	getline(cin, str1);
	getline(cin, str2);
	len1 = str1.size();
	len2 = str2.size();
	cnt[len1][len2] = 1;
	memset(d, -1, sizeof(d));
}

int dp (int a, int b) {
	if (a == len1 && b == len2) {
		return 0;
	}
	if (d[a][b] != -1) return d[a][b];
	int &ans = d[a][b];
	ans = INFINITE;
	if (a == len1) {
		ans = dp(a, b+1) + 1;
		cnt[a][b] = cnt[a][b+1];
	} else if (b == len2) {
		ans = dp(a+1, b) + 1;
		cnt[a][b] = cnt[a+1][b];
	} else {
		if (str1[a] == str2[b]) {
			ans = dp(a+1, b+1) + 1;
			cnt[a][b] = cnt[a+1][b+1];
		} else {
			ans = min(dp(a+1, b) + 1, dp(a, b+1) + 1);
			if (d[a+1][b] == d[a][b+1]) cnt[a][b] = cnt[a+1][b] + cnt[a][b+1];
			else if (d[a+1][b] < d[a][b+1]) cnt[a][b] = cnt[a+1][b];
			else if (d[a+1][b] > d[a][b+1]) cnt[a][b] = cnt[a][b+1];
		}
	}
	return ans;
}

int main () {
	int T;
	cin >> T;
	getline(cin, str1);
	for (int t = 1; t <= T; t++) {
		init();
		int x = dp(0, 0);
		cout << "Case #" << t << ": " << x << " " << cnt[0][0] << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/AdamAndTina/article/details/88934859