UVA 1625
来源:互联网 发布:windows字体怎么设置 编辑:程序博客网 时间:2024/04/30 18:56
- 题目大意
- 思路
- 代码
- Hit
题目大意
传送门
输入两个长度分别为n和m的颜色序列,要求按顺序合并为一个序列,要求每次把序列开头的颜色方法新序列的尾部。
现在有一个衡量标准L(c),L(c)表示的是颜色c的跨度:最大位置和最小位置之差。
对于字符串
当合并为
思路
使用dp[i][j]
表示从S1中取出前i个字符,以及从S2中取出前j个字符,组成字符串,这个字符串L(c)的sum值。
那么可以得到以下状态转移方程:
for(int i = 0; i <= len1; i++) { for(int j = 0; j <= len2; j++) { //将S1[i]插入到dp[i-1][j]中 if(i>0) dp[i][j] = min(dp[i][j],dp[i-1][j] + cnt[i-1][j]); //将S2[j]插入到dp[i][j-1]中 if(j>0) dp[i][j] = min(dp[i][j],dp[i][j-1] + cnt[i][j-1]); } }
cnt[i][j]表示从字符S1中取出前i个字符,从字符S2中取出前j个字符,组成的字符串中,已经出现但是没有结束的字母的个数。
//cnt[i][j]字符串S1[i] + S2[j] 中已经开始但是没有结束的字母的个数 for(int i = 0; i<= len1; i++) { for(int j = 0; j <= len2; j++) { for(int c = 0; c < 26; c++) { if((c_list[c].l1 <= i || c_list[c].l2 <= j) && (c_list[c].r1 > i || c_list[c].r2 > j) ) cnt[i][j]++; } } }
代码
#include<stdio.h>#include<cstring>#include<set>#define maxn 5005#define INF 1<<30#define min(a,b) (a>b)? b:a#define max(a,b) (a>b)? a:busing namespace std;char S1[maxn];char S2[maxn];int dp[maxn][maxn];int cnt[maxn][maxn];struct Node{ int l1;//字符串S1中字母i的左边界 int r1;//字符串S1中字母i的右边界 int l2;//字符串S2中字母i的左边界 int r2;//字符串S2中字母i的右边界};Node c_list[27];int main (){ int n; scanf("%d",&n); while(n--) { scanf("%s",S1); scanf("%s",S2); int len1 = strlen(S1); int len2 = strlen(S2); for(int i = 0; i<26; i++) { c_list[i].l1 = maxn+1; c_list[i].r1 = -1; c_list[i].l2 = maxn+1; c_list[i].r2 = -1; } for(int i = 0; i<len1; i++) { c_list[S1[i]-'A'].l1 = min(c_list[S1[i]-'A'].l1,i); c_list[S1[i]-'A'].r1 = max(c_list[S1[i]-'A'].r1,i); } for(int i = 0; i<len2; i++) { c_list[S2[i]-'A'].l2 = min(c_list[S2[i]-'A'].l2,i); c_list[S2[i]-'A'].r2 = max(c_list[S2[i]-'A'].r2,i); } for(int i = 0;i<26;i++){ c_list[i].l1 +=1; c_list[i].r1 +=1; c_list[i].l2 +=1; c_list[i].r2 +=1; //printf("%c [%d %d] [%d %d]\n",i+'A',c_list[i].l1,c_list[i].r1,c_list[i].l2,c_list[i].r2); } for(int i = 0; i <= len1; i++) { for(int j = 0; j <= len2; j++) { dp[i][j] = INF; cnt[i][j] = 0; } } dp[1][0] = 0; dp[0][1] = 0; //cnt[i][j]字符串S1[i] + S2[j] 中已经开始但是没有结束的字母的个数 for(int i = 0; i<= len1; i++) { for(int j = 0; j <= len2; j++) { for(int c = 0; c < 26; c++) { if((c_list[c].l1 <= i || c_list[c].l2 <= j) && (c_list[c].r1 > i || c_list[c].r2 > j) ) cnt[i][j]++; } } }/* for(int i = 0;i<=len1;i++){ for(int j = 0; j <= len2; j++){ printf("%d\t",cnt[i][j]); } printf("\n"); }*/ for(int i = 0; i <= len1; i++) { for(int j = 0; j <= len2; j++) { //将S1[i]插入到dp[i-1][j]中 if(i>0) dp[i][j] = min(dp[i][j],dp[i-1][j] + cnt[i-1][j]); //将S2[j]插入到dp[i][j-1]中 if(j>0) dp[i][j] = min(dp[i][j],dp[i][j-1] + cnt[i][j-1]); } }/* printf("\n\n"); for(int i = 0; i <= len1; i++){ for(int j = 0; j <= len2; j++){ printf("%d\t",dp[i][j]); } printf("\n"); }*/ printf("%d\n",dp[len1][len2]); }}/*GBBYYRRGB*/
Hit
字符串相关的dp问题,最好是将字符串的起点设置为1,而不是0,这样会省去很多-1或者是+1的边界处理问题。
阅读全文
0 0
- UVa 1625
- UVa 1625
- UVA 1625
- Uva-1625-Color Length
- UVA 1625 Color Length
- UVA-1625 Color Length
- uva 1625 color length
- UVA 1625 Color Length
- UVA 1625 Color Length
- UVA 1625 Color Length
- UVa 1625 Color Length
- UVA 1625 Color Length
- UVA 1625 Color Length
- uva
- UVA
- UVA
- UVA
- uva
- 如何获取登录Oracle数据库的客户端IP等会话信息
- Java开发中的23种设计模式详解(转)
- Python作用域与带有循环变量的默认参数相比较
- android 加载gif动图 自定义GifView
- PHP给前端返回一个JSON‘对象’
- UVA 1625
- javascript无法处理位数大于16位的整数
- 块级元素的一些小问题
- c++11 override and final
- 关于Fragment中getActivity为Null的问题
- Linux系统目录结构
- flow
- java.lang.NoClassDefFoundError: org/hamcrest/MatcherAssert 的解决办法
- 阿里云加密服务使用教程