SPOJ 3408 DNA Sequences
2014-03-22 14:55
155 查看
有点卡,一直纠结于dp数组转移相关sum数组转移的问题,看了下别人的题解发现,其实独立开来就行了。求最长公共子序列,且每一连续子段的长度不小于k。用sum数组记录前面有多少连续的序列。sum[i][j] 只能由sum[i - 1][j - 1]转移而来。sum数组的转移与dp数组的转移独立开来。当sum[i][j] > k时,可以选择从前一位连过来,也可以从前k位连过来。[i,j]序列还是表示当前位置的状态好点,若表示[i - 1, j - 1]的状态则最后会略纠结。
#include <cstdio> #include <algorithm> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> using namespace std; typedef long long LL; #define N 1005 int sum ; int dp ; int k; char a ; char b ; int main(){ dp[0][0] = 0; dp[0][1] = 0; dp[1][0] = 0; while(scanf("%d", &k) , k){ scanf("%s", a + 1); scanf("%s", b + 1); int lena = strlen(a + 1); int lenb = strlen(b + 1); for(int i = 1; i <= lena; i++){ for(int j = 1; j <= lenb; j++){ sum[i][j] = 0; if(a[i] == b[j]){ sum[i][j] = sum[i - 1][j - 1] + 1; } dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); if(sum[i][j] == k){ dp[i][j] = max(dp[i][j], dp[i - k][j - k] + k); } if(sum[i][j] > k){ dp[i][j] = max(dp[i - k][j - k] + k, dp[i - 1][j - 1] + 1); } } } printf("%d\n", dp[lena][lenb]); } return 0; }
相关文章推荐
- spoj 3408 动态规划
- SPOJ GONE G-One Numbers(数位dp)
- SPOJ QTREE4 Query on a tree IV (边分治 + 堆)
- spoj 1811 LCS - Longest Common Substring (后缀自动机)
- SPOJ FAVDICE
- spoj287 经典网络流题目,二分+网络流判定方案
- spoj -705 New Distinct Substrings--后缀数组
- SPOJ QTREE Query on a tree
- SPOJ DISUBSTR Distinct Substrings
- 【SPOJ】QTREE 1 树链剖分裸题
- SPOJ DIVSUM - Divisor Summation
- spoj375 Query on a tree(树链剖分 边权 入门题)
- Leetcode-187.Repeated DNA Sequences
- 2400: Spoj 839 Optimal Marks 最小割
- SPOJ SUBST1 New Distinct Substrings
- 【 bzoj 2400 】Spoj 839 Optimal Marks - 最小割
- spoj 8222 Substrings(后缀自动机+DP)
- 【SPOJ-GSS6】Can you answer these queries VI【Splay】
- SPOJ GSS
- 【SPOJ-PALIN】The Next Palindrome【模拟】