#51nod 1183 编辑距离
##解题思路
开始想的用两个字符串的最大长度减去两个字符串的最长公共子串,想当然了。这就要求我们做题的时候一定要考虑全面,不放过一个细节。
再说做法,跟最长公共子串的做法相似,动态规划。
##代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char str1[1010], str2[1010];
int dp[1010][1010];
int len1, len2;
int main(){
int i, j;
scanf("%s", str1);
scanf("%s", str2);
len1 = strlen(str1);
len2 = strlen(str2);
for(i = 1; i <= len1; ++i)
dp[i][0] = i;
for(i = 1; i <= len2; ++i)
dp[0][i] = i;
for(i = 0; i < len1; ++i){
for(j = 0; j < len2; ++j){
dp[i + 1][j + 1] = min(min(dp[i + 1][j], dp[i][j + 1]) + 1, dp[i][j] + !(str1[i] == str2[j]));
}
}
printf("%d\n", dp[len1][len2]);
return 0;
}
##问题
- 为什么那三种情况就是全部的子问题?
- 某个字符串增加一个字符对两个字符串编辑距离的影响?
#51nod 1185 威佐夫游戏V2
##解题思路
威佐夫游戏,判断是否是奇异局势,再对精度的问题处理一下。
##代码
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef unsigned long long ULL;
const double cnm = (sqrt(5) + 1) / 2;
const ULL Gold[3] = {618033988, 749894848, 204586834};
const ULL MOD = 1000000000;
int main(){
int t;
ULL a, b, c;
scanf("%d", &t);
while(t--){
scanf("%llu%llu", &a, &b);
if(a > b) swap(a, b);
ULL dist = b - a;
ULL pre = dist / MOD, las = dist % MOD;
ULL a1 = las * Gold[2];
ULL a2 = pre * Gold[2] + las * Gold[1] + a1 / MOD;
ULL a3 = pre * Gold[1] + las * Gold[0] + a2 / MOD;
ULL a4 = dist + pre * Gold[0] + a3 / MOD;
printf("%c\n", a4 == a ? 'B' : 'A');
}
return 0;
}
##问题
- 对精度控制的方式