UVA - 1625 Color Length[序列DP 提前计算代价]
2016-10-21 16:48
417 查看
UVA - 1625 Color Length |
白书
很明显f[i][j]表示第一个取到i第二个取到j的代价
问题在于代价的计算,并不知道每种颜色的开始和结束
和模拟赛那道环形DP很想,计算这次转移会给其他的元素带来的代价,也就是转移前已经出现但还没结束的元素都会代价+1
预处理每种颜色在两个序列中出现的位置bg[i][0/1]和ed[i][0/1],
计算f[i][j]时同时计算w[i][j]为(i,j)这个状态已经出现还没结束的个数
注意bg要先初始化为INF,计算w:
if(bg[c][0]==i&&bg[c][1]>j) w[i][j]++; if(ed[c][0]==i&&ed[c][1]<=j) w[i][j]--;
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
const int N=5005,INF=1e9;
int T,n,m;
char a
,b
;
int f
,w
,bg[27][2],ed[27][2];
void dp(){
memset(bg,0,sizeof(bg));
memset(ed,0,sizeof(ed));
for(int i=0;i<26;i++) bg[i][0]=bg[i][1]=INF;
for(int i=1;i<=n;i++){
int c=a[i]-'A';
if(bg[c][0]==INF) bg[c][0]=i;
ed[c][0]=i;
}
for(int i=1;i<=m;i++){
int c=b[i]-'A';
if(bg[c][1]==INF) bg[c][1]=i;
ed[c][1]=i;
}
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++){
//f[i][j]=min(f[i-1][j]+cal(i-1,j),f[i][j-1]+cal(i,j-1));
//f[i][j]=min(f[i-1][j],f[i][j-1])+cal(i,j);
if(i==0&&j==0) continue;
int t1=INF,t2=INF;
if(i>0) t1=f[i-1][j]+w[i-1][j];
if(j>0) t2=f[i][j-1]+w[i][j-1];
f[i][j]=min(t1,t2);
if(i>0){
w[i][j]=w[i-1][j];
int c=a[i]-'A';
if(bg[c][0]==i&&bg[c][1]>j) w[i][j]++; if(ed[c][0]==i&&ed[c][1]<=j) w[i][j]--;
}else{
w[i][j]=w[i][j-1];
int c=b[j]-'A';
if(bg[c][1]==j&&bg[c][0]>i) w[i][j]++;
if(ed[c][1]==j&&ed[c][0]<=i) w[i][j]--;
//if(b[j]=='R') printf("R %d %d %d %d\n",bg[c][1],ed[c][1],i,j);
}
//printf("%d %d %d %d\n",i,j,f[i][j],w[i][j]);
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%s%s",a+1,b+1);
n=strlen(a+1);m=strlen(b+1);
dp();
printf("%d\n",f
[m]);
}
}
白书的标程用了滚动数组,可以借鉴一下
// UVa1625 Color Length // Rujia Liu #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 5000 + 5; const int INF = 1000000000; char p[maxn], q[maxn]; // starts from position 1 int sp[26], sq[26], ep[26], eq[26]; // sp[i] start positions of character i in p int d[2][maxn], c[2][maxn]; // 滚动数组 c[i][j]: how many "incomplete" colors in the mixed sequence int main() { int T; scanf("%d", &T); while(T--) { scanf("%s%s", p+1, q+1); int n = strlen(p+1); int m = strlen(q+1); for(int i = 1; i <= n; i++) p[i] -= 'A'; for(int i = 1; i <= m; i++) q[i] -= 'A'; // calculate s and e for(int i = 0; i < 26; i++) { sp[i] = sq[i] = INF; ep[i] = eq[i] = 0; } for(int i = 1; i <= n; i++) { sp[p[i]] = min(sp[p[i]], i); ep[p[i]] = i; } for(int i = 1; i <= m; i++) { sq[q[i]] = min(sq[q[i]], i); eq[q[i]] = i; } // dp int t = 0; memset(c, 0, sizeof(c)); memset(d, 0, sizeof(d)); for(int i = 0; i <= n; i++) { for(int j = 0; j <= m; j++) { if(!i && !j) continue; // calculate d int v1 = INF, v2 = INF; //计算d[i][j], d[i][j]由d[i-1][j]或d[i][j-1]添加一个字母得到 if(i) v1 = d[t^1][j] + c[t^1][j]; // remove from p if(j) v2 = d[t][j - 1] + c[t][j - 1]; // remove from q d[t][j] = min(v1, v2); // calculate c if(i) { c[t][j] = c[t^1][j]; if(sp[p[i]] == i && sq[p[i]] > j) c[t][j]++; //出现新的字母 if(ep[p[i]] == i && eq[p[i]] <= j) c[t][j]--; //一个字母已经结束 } else if(j) { c[t][j] = c[t][j - 1]; if(sq[q[j]] == j && sp[q[j]] > i) c[t][j]++; if(eq[q[j]] == j && ep[q[j]] <= i) c[t][j]--; } } t ^= 1; } printf("%d\n", d[t^1][m]); } return 0; }
相关文章推荐
- UVa 1625 color length--dp状态转移的巧妙计算
- UVa1625 Color Length(DP)
- 洛谷P1220关路灯[区间DP 提前计算代价]
- UVA 1625 Color Length——dp
- uva 1625 - Color Length(dp 里面 L C S 问题解决方式变形)
- 例题9-8 UVA 1625 Color Length(DP)
- UVa 1625 Color Length (DP)
- uva 1625 Color Length (dp)
- Color Length - UVa 1625 dp
- UVA 1625 Color Length 颜色的长度 (预处理+dp)
- UVa1625 Color length[DP][差分]
- UVA - 1625 D - Color Length——DP
- UVA1625 - Color Length (DP)
- Color Length UVA - 1625 (线性dp)
- BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]
- Uva1625 -Color Length(DP)
- UVa 1625:Color Length(DP)
- UVA 1625 - Color Length【DP】
- 【DP模型:LCS】uva1625 Color Length
- Stacking Boxes +uva+dp(最长严格降子序列的变形)