题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5791
题意:给出两个串,求出其子集相同的个数,若元素的位置不同即算两种。
想法:刚那到手时确实没有想法,但一看数据范围
1000∗1000
,那不用说了,肯定是DP。我们设dp[i][j]表示考虑到串S第i位和串T第j位时的答案。那么很明显s[i]和t[j]是否相等决定了转移的方式不同。其中,s[i]
=
t[j]时,dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + 1,而s[i]
代码如下:
#include <cstdio>
#include <cstring>
typedef long long ll;
const int MOD = 1000000007;
const int MAXN = 1000 + 10;
int a[MAXN], b[MAXN];
ll dp[MAXN][MAXN];
int main(){
//freopen("p.in", "r", stdin);
int n, m;
while(~scanf("%d %d", &n, &m)){
for(int i = 1; i <= n; ++i){
scanf("%d", a + i);
}
for(int i = 1; i <= m; ++i){
scanf("%d", b + i);
}
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
if(a[i] == b[j]){
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1] + 1) % MOD;
}else{
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + MOD) % MOD;
}
}
}
printf("%I64d\n", dp[n][m]);
}
return 0;
}