hdu 5791 Two 二维dp

Two

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 889    Accepted Submission(s): 405


Problem Description
Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not same. A' is a subsequence of A. B' is a subsequence of B. The subsequnce can be not continuous. For example, {1,1,2} has 7 subsequences {1},{1},{2},{1,1},{1,2},{1,2},{1,1,2}. The answer can be very large. Output the answer mod 1000000007.
 
Input
The input contains multiple test cases.

For each test case, the first line cantains two integers N,M(1N,M1000). The next line contains N integers. The next line followed M integers. All integers are between 1 and 1000.
 
Output
For each test case, output the answer mod 1000000007.
 
Sample Input
3 2 1 2 3 2 1 3 2 1 2 3 1 2
 
Sample Output
2 3
 
Author
ZSTU
 
Source
 题意:给你a,b两个数组,可以从a数组中按顺序选出一些数字,然后b数组按顺序选出一些数字,要求
最后选出的数字按顺序相同,有多少选法。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
typedef  long long  ll;
typedef unsigned long long ull;
#define MM(a,b) memset(a,b,sizeof(a));
#define inf 0x7f7f7f7f
#define FOR(i,n) for(int i=1;i<=n;i++)
#define CT continue;
#define PF printf
#define SC scanf
const int mod=1000000007;
const int N=1000+10;
ull seed=13331;
ll dp[N][N];
int a[N],b[N];

int main()
{
    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]);

        MM(dp,0);
        for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
                   {
                       dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mod)%mod;
                       if(a[i]==b[j]) dp[i][j]=(dp[i][j]+dp[i-1][j-1]+1)%mod;
                   }
        printf("%lld
",dp[n][m]);
    }
    return 0;
}

  分析:昨天比赛的时候一直想着怎么把暴力的复杂度降下去,想到了哈希,大数。。。就是将各种情况的对应到一个数值,,,,然并卵,,因为这道题目取的数字可以是不连续的,哈希跟大数就跪了。

正确解法:设dp[i][j]为当前枚举到a是i位,b是j位的时候,那么先撇开(i,j)不看,那么

dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];(注意dp[i-1][j-1]多算了一次

如果a[i]==b[j],那么(i,j)还可以单独的产生组合,;

最后要注意%mod时,两者相减可能会产生负数

感觉取得数字要是不是连续的话一般就要上dp了

原文地址:https://www.cnblogs.com/smilesundream/p/5732319.html