HDU 5282 Senior's String DP(LCS变形)
2017-10-12 10:53
627 查看
HDU 5282
题意:给出两个字符串a,b.假如a,b的LCS长度为L,从a中选出子序列长度为LCS并且该子序列在b中出现,问有多少种方案?
| a|,|b|<=1e3. (长度为L的子序列有2^L个).两个子序列有某个位置选择的下标不同就视为个不同.
dp[i][j]:a的前缀i和b的前缀j的LCS长度.
f[i][j]:a的前缀i有多少个长度为dp[i][j]的子序列出现在b的前缀j中.
然后现在考虑选不选a的第i个字符.
不选a[i],则需要dp[i-1][j]=dp[i][j].
选a[i],则此时的LCS最后一个字符为a[i] 找到b的前缀j中字符a[i]最后一次出现的位置p
则如果选a[i] 则要满足dp[i-1][p-1]+1=dp[i][j].
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,inf=0x3f3f3f3f;
const ll mod=1e9+7;
char a
,b
;
ll dp
,f
;
int last[27];
int main()
{
int T;
cin>>T;
while(T--)
{
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
scanf("%s%s",a+1,b+1);
int n=strlen(a+1),m=strlen(b+1);
f[0][0]=1;
for(int j=1;j<=m;j++)
f[0][j]=1;
for(int i=1;i<=n;i++)
{
f[i][0]=1;
memset(last,-1,sizeof(last));
for(int j=1;j<=m;j++)
{
last[b[j]-'a']=j;
if(a[i]==b[j])
dp[i][j]=dp[i-1][j-1]+1;
dp[i][j]=max(dp[i][j],max(dp[i-1][j],dp[i][j-1]));
if(dp[i-1][j]==dp[i][j])
f[i][j]=f[i-1][j];
int p=last[a[i]-'a'];
if(p!=-1)
{
if(dp[i-1][p-1]+1==dp[i][j])
f[i][j]=(f[i][j]+f[i-1][p-1])%mod;
}
}
}
printf("%lld\n",f
[m]);
}
return 0;
}
题意:给出两个字符串a,b.假如a,b的LCS长度为L,从a中选出子序列长度为LCS并且该子序列在b中出现,问有多少种方案?
| a|,|b|<=1e3. (长度为L的子序列有2^L个).两个子序列有某个位置选择的下标不同就视为个不同.
dp[i][j]:a的前缀i和b的前缀j的LCS长度.
f[i][j]:a的前缀i有多少个长度为dp[i][j]的子序列出现在b的前缀j中.
然后现在考虑选不选a的第i个字符.
不选a[i],则需要dp[i-1][j]=dp[i][j].
选a[i],则此时的LCS最后一个字符为a[i] 找到b的前缀j中字符a[i]最后一次出现的位置p
则如果选a[i] 则要满足dp[i-1][p-1]+1=dp[i][j].
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,inf=0x3f3f3f3f;
const ll mod=1e9+7;
char a
,b
;
ll dp
,f
;
int last[27];
int main()
{
int T;
cin>>T;
while(T--)
{
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
scanf("%s%s",a+1,b+1);
int n=strlen(a+1),m=strlen(b+1);
f[0][0]=1;
for(int j=1;j<=m;j++)
f[0][j]=1;
for(int i=1;i<=n;i++)
{
f[i][0]=1;
memset(last,-1,sizeof(last));
for(int j=1;j<=m;j++)
{
last[b[j]-'a']=j;
if(a[i]==b[j])
dp[i][j]=dp[i-1][j-1]+1;
dp[i][j]=max(dp[i][j],max(dp[i-1][j],dp[i][j-1]));
if(dp[i-1][j]==dp[i][j])
f[i][j]=f[i-1][j];
int p=last[a[i]-'a'];
if(p!=-1)
{
if(dp[i-1][p-1]+1==dp[i][j])
f[i][j]=(f[i][j]+f[i-1][p-1])%mod;
}
}
}
printf("%lld\n",f
[m]);
}
return 0;
}
相关文章推荐
- HDU 5282 Senior's String (两次dp LCS预处理)
- hdu 5282 Senior's String 两次dp
- HDU 1087 lcs变形 (简单DP)
- hdu 5282 Senior's String 两次dp
- HDU 5707 Combine String (DP,LCS变形)
- HUST 4681 String (DP LCS变形)
- HDU 4681 String (dp, LCS | 多校8)
- hdu 1080(LCS变形)
- hdu2476——String painter(区间DP)
- BestCoder Round #47 ($)(hdu5280 - 5282)dp最长公共子序列变形
- HDU 2476 String painter(区间dp)
- HDU - 3336 Count the string(KMP+DP)
- HDU 5256 序列变换 (DP/LIS变形)
- HDU 2476 String painter(区间DP啊)
- Hdu 3336 Count the string (KMP+DP 前缀出现次数和)
- HDU - 3336 Count the string(kmp+dp)
- hdu 1501 简单dp (最长公共子串的变形)
- 【HDU 3336】Count the string(KMP+DP)
- HDU 2476 String painter (区间DP)
- HDU-2476-String painter【区间DP】