每日一题(17): poj1080

来源:互联网 发布:java时间戳是什么 编辑:程序博客网 时间:2024/06/03 19:57
1. 原来没有思路。因为LCS有点不熟。但是参考了网上的解法,有了思路,就自己写出来了。主要参考:点击打开链接

2. 其实就是把之前的动态规划公式延伸了一维。因为之前虽然背包问题也可以是二维,但是毕竟可以化为一维。因为后一种状态只和其中一个index(j)有关。这也是可以化为一维的原因。但是此题不同,就是二维。当然,如果熟悉LCS,就可能会容易一点。公式:

dp[i][j] = max{dp[i-1][j-1]+value(a[i],b]j],dp[i][j-1]+value(-,b[j]), dp[i-1][j]+value(a[i],-)}

3. 注意边界。一边是0,就用‘-’,另一边字符串用字符。这应该可以理解的,也就是从实际上说的通的。00是0。

4. 为了保证有0边界,输入的时候需要对scanf里面的地址加1.这一点之前没有用过。

5. 因为在max里面的a写成b,导致出错。一定要小心。写程序的过程尤其慎重。因为debug的时候很困难。

下面是代码:

#include<iostream>#include<stdio.h>#include<string.h>using namespace std;//数据结构和变量const int maxn = 110;char a[maxn];char b[maxn];int dp[maxn][maxn];int n1,n2;int score[5][5]={{5,-1,-2,-1,-3},{-1,5,-3,-2,-4},{-2,-3,5,-2,-2},{-1,-2,-2,5,-1},{-3,-4,-2,-1,0}};//取两者之间的最大值int big(int temp1,int temp2,int temp3){int result = temp1;if(result<temp2)result=temp2;if(result<temp3)result = temp3;return result;}//返回字母对应的下标。其实可以用hash的int charIndex(char temp1){int result;switch(temp1){case 'A': result = 0;break;case 'C': result = 1;break;case 'G': result = 2;break;case 'T': result = 3;break;case '-': result = 4;break;}return result;}//返回对比值int value(char temp1, char temp2){return score[charIndex(temp1)][charIndex(temp2)];}int main(){//freopen("input.txt","r",stdin);int t;cin >>t ;int i,j;while(t--){//cin>>n1;//输入数据//此法甚妙scanf("%d%s",&n1,a+1);scanf("%d%s",&n2,b+1);//初始化:边界dp[0][0] = 0;for(i = 1; i<=n1; i++){dp[i][0] = value(a[i],'-')+dp[i-1][0];}for(j = 1; j<=n2; j++){dp[0][j] = value(b[j],'-')+dp[0][j-1];}//开始动态规划://公式dp[i][j] = max{dp[i-1][j-1]+value(a[i],b]j],dp[i][j-1]+value(-,b[j]), dp[i-1][j]+value(b[i],-)}for(i = 1; i<=n1; i++){for(j = 1; j<=n2; j++){dp[i][j] = big(dp[i-1][j-1]+value(a[i],b[j]),dp[i][j-1]+value('-',b[j]), dp[i-1][j]+value(a[i],'-'));}}//输出结果cout <<dp[n1][n2]<<endl;}}


0 0
原创粉丝点击