/*
Uva1625
题意:给你两个序列A B, 每次可以从其中一个序列的头部拿出一个字符放到新序列C的末尾,定义C序列的优美度为每个字符结束位置减去开始
位置, 现在让你最小化优美度。
tag: dp
分析:我们转换思维, 当从其中一个序列拿出一个放到C的末尾的时候这个字符是对答案有贡献的, 他的贡献值就是当前已经开始但未结束
的字符的个数。 因此我们定义dp[i][j] 为A序列1 - i, B序列1 - j能构造的字符串的最少优美度, 那么dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + w[i][j]
其中w[i][j]为当前已经开始但未结束的字符的个数。
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int maxn = 5000 + 100;
char str1[maxn], str2[maxn];
int len1, len2;
int r1[30], r2[30];
int dp[maxn][maxn];
int main() {
int T; scanf("%d", &T);
while(T--) {
scanf("%s%s", str1+1, str2+1);
len1 = strlen(str1+1); len2 = strlen(str2+1);
memset(r1, -1, sizeof(r1));
memset(r2, -1, sizeof(r2));
for(int i=1; i<=len1; i++) {
int idx = str1[i] - 'A';
if(r1[idx] == -1) r1[idx] = i;
else r1[idx] = max(r1[idx], i);
}
for(int i=1; i<=len2; i++) {
int idx = str2[i] - 'A';
if(r2[idx] == -1) r2[idx] = i;
else r2[idx] = max(r2[idx], i);
}
set<char> st;
dp[0][0] = 0;
for(int i=0; i<=len1; i++){
if(i) st.insert(str1[i]);
set<char> tpst = st;
for(int j=0; j<=len2; j++) {
if(i==0 && j==0) continue;
int tp = 0x3f3f3f3f;
if(i-1>=0) tp = min(tp, dp[i-1][j]);
if(j-1>=0) tp = min(tp, dp[i][j-1]);
if(j) tpst.insert(str2[j]);
for(int k=0; k<26; k++) {
if(i>=r1[k] && j>=r2[k])
tpst.erase('A'+k);
}
dp[i][j] = tp + tpst.size();
}
}
printf("%d\n", dp[len1][len2]);
}
return 0;
}
<pre name="code" class="cpp">/*
Uva 10003
题意:给你一个长度为l的棍子, 有n个切割点, 你的任务是把这个棍子切成n+1块, 使得总的切割费用最小。
tag: dp
分析: 我们定义dp[i][j]为切割木棍的i - j的最小费用那么dp[i][j] = min(dp[i][k] + dp[k][j] + a[j] - a[i]) .. 复杂度O(n^2)此题还有四边形不等式
的优化方法待更。
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int l, n;
int a[100], na;
int dp[100][100];
int dfs(int l, int r) {
if(dp[l][r] != -1) return dp[l][r];
if(r-l == 1) return dp[l][r] = 0;
int res = 0x3f3f3f3f;
for(int i=l+1; i<r; i++)
res = min(res, a[r]-a[l]+dfs(l, i)+dfs(i, r));
return dp[l][r] = res;
}
int main() {
while(scanf("%d", &l)==1 && l) {
scanf("%d", &n);
na = 0;
a[na++] = 0;
for(int i=1; i<=n; i++) {
int t; scanf("%d", &t);
a[na++] = t;
}
a[na++] = l;
memset(dp, -1, sizeof(dp));
int res = dfs(0, na-1);
printf("The minimum cutting is %d.\n", res);
}
return 0;
}