hdu 5791 dp

来源:互联网 发布:抗衰老精华 知乎 编辑:程序博客网 时间:2024/06/03 07:35

 


链接:戳这里


Two

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

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(1≤N,M≤1000). 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
 


题意:

分别给出长度为n,m的序列,问有多少子序列a和b相等,ab元素的相对原数组位置一样


思路:

都知道是dp,说清楚点吧

dp[i][j] 表示当前a序列到位置i,b序列到位置j的子序列数目

if(a[i]!=b[j]) dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]  

当前a[i]!=b[j] 那么需要继承[1,i]与[1,j-1]的相同子序列数目,同理[1,i-1]与[1,j]也需要继承。但是在继承的时候,多算了[1,i-1]与[1,j-1]的,仔细看看前面的[i-1,j] && [i,j-1]都包含了[i-1,j-1],所以会多算一次,减去就可以了

if(a[i]==b[j]) dp[i][j]=dp[i-1][j]+dp[i][j-1]+1

和前面一样,先不考虑a[i]与b[j]的关系,统计之前的值并继承。dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1],现在来考虑a[i]==b[j]对当前[i,j]的贡献,前面提到了[i-1,j-1]算加了两次,要减掉一次。

这里需要把a[i]这个元素加到一次的[i-1,j-1]上去 ,使得前面的相同子序列用上a[i],然后就有dp[i-1][j-1]次,加上就可以了,至于为什么+1,显然{ a[i] & b[j] }可以单独做一个子序列啊。来组数据模拟一下吧

a:1 2 3 4 5

b:1 3 4 5 1

假设当前枚举到:[4,3] 且a[4]==b[3]

a=1 2 3 4

b=1 3 4

dp[4][3]=dp[4][2]+dp[3][3]  (当前没有考虑a[4]==b[3]进去

dp[4][2]&dp[3][3],当前对应的子序列为:{a=1,b=1}、{a=3,b=3}、{a=1,3 , b=1,3 }  & {a=1,b=1}、{a=3,b=3}、{a=1,3 , b=1,3 }

显然多算了一次dp[3][2],那么我在多算的这dp[3][2]三次里面加上一个元素a[4]:

{a=1,b=1}、{a=3,b=3}、{a=1,3 , b=1,3 }  & {a=1,4 , b=1,4 }、{a=3,4 , b=3,4 }、{a=1,3,4 , b=1,3,4 }

所以不需要减去dp[3][2],后面+1 -> 子序列{4,4}


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<iomanip>#include<cmath>#include<bitset>#define mst(ss,b) memset((ss),(b),sizeof(ss))///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef long double ld;#define INF (1ll<<60)-1#define Max 1e9const ll mod=1000000007;using namespace std;int n,m;ll dp[1010][1010];int a[1010],b[1010];int main(){    while(scanf("%d%d",&n,&m)!=EOF){        for(int i=1;i<=n;i++) scanf("%d",&a[i]);        for(int i=1;i<=m;i++) scanf("%d",&b[i]);        mst(dp,0);        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;                dp[i][j]%=mod;            }        }        printf("%I64d\n",(dp[n][m]%mod+mod)%mod);    }    return 0;}



0 0
原创粉丝点击