1. 程式人生 > >Two HDU - 5791 dp

Two HDU - 5791 dp

題解

題目大意 給你兩個數列讓你求公共子序列數量

使用動態規劃求解 d[i][j]表示a數列的前i個長度和b數列的前j個長度的公共子序列的數量 遍歷a和b的每個位置
如果當前位置不相等則等於 a長度-1的+b長度-1的答案再減去重複的部分a和b長度-1的答案
d[i][j] = d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1]
如果當前位置相等則等於 不相等的答案+a和b長度都減一的答案(在前面追加當前字元)+單獨的當前字元的一個答案
d[i][j] = d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1] + d[i - 1][j - 1] + 1
d[i - 1][j - 1]可以約掉

AC程式碼

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int MAXN = 1e3 + 10;
ll d[MAXN][MAXN]; //a前i位 b前j位
int a[MAXN], b[MAXN];

int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin)
; #endif int N, M; while (cin >> N >> M) { memset(d, 0, sizeof(d)); for (int i = 1; i <= N; i++) scanf("%d", &a[i]); for (int i = 1; i <= M; i++) scanf("%d", &b[i]); for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) { if (a[i] == b[j]
) //相同則等於不相同的加上a和b都減1後面追加當前 和當前相同的1貢獻 化簡得式子 d[i][j] = d[i - 1][j] + d[i][j - 1] + 1 % MOD; else //如果當前位不同則等於a長度減1加b長度減1並減去長度都減1的重複部分 d[i][j] = (d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1] + MOD) % MOD; } cout << d[N][M] << endl; } return 0; }