Two HDU - 5791 dp
阿新 • • 發佈:2018-12-23
題解
題目大意 給你兩個數列讓你求公共子序列數量
使用動態規劃求解 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;
}