Lightoj1013【DP_LCS】
2024-09-03 23:47:56
题意:
给你两个字符串,让你求一个最短字符串,其中存在给出串的种类;
求这个字符串的长度和种类;
思路:
//dp[i,j,k]表示前i个字符,包含s1串前j个字母,包含s2串前k个字符时的方案数。
//按照一定的顺序,碰到相同元素只会留一个,不同元素这个位置就有两种情况
#include<cstdio>
#include<math.h>
#include<queue>
#include<map>
#include<string>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL mod=1e9+7; const int N=50;
char s1[N],s2[N];
int len[N][N];
LL dp[100][N][N];
int LCS()
{
int n,m;
n=strlen(s1+1);
m=strlen(s2+1);
memset(len,0,sizeof(len));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(s1[i]!=s2[j])
len[i][j]=max(len[i-1][j],len[i][j-1]);
else
len[i][j]=len[i-1][j-1]+1;
}
}
return n+m-len[n][m];
} LL solve(int length)
{
int n,m;
n=strlen(s1+1);
m=strlen(s2+1);
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for(int i=1;i<=length;i++)
{
dp[i][0][i]=1;
dp[i][i][0]=1;
for(int j=1;j<=min(n,i);j++)
{
for(int k=1;k<=min(m,i);k++)
{
if(s1[j]==s2[k])
dp[i][j][k]=dp[i-1][j-1][k-1];
else
dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j][k-1];
}
}
}
return dp[length][n][m];
} int main()
{
int T,cas=1;
int ans1;
LL ans2;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s1+1,s2+1);
ans1=LCS();
ans2=solve(ans1);
printf("Case %d: %d %lld\n",cas++,ans1,ans2);
}
return 0;
}
最新文章
- 【转】mysql忘记密码(未初始化)
- 如何定位死循环或高CPU使用率(linux)
- Spring 3.x jar 包详解 与 依赖关系
- 【bzoj1040】骑士
- jQuery判断元素是否在可视区
- Json转换插件
- sql 几个常用函数
- JavaScript 语法陷阱
- c++11 右值引用、move、完美转发forward<;T>;
- java底层学习---1
- NOIWC2018游记
- OC语言(一)
- 用django2.1开发公司官网(上)
- python自动化开发-[第二十一天]-form验证,中间件,缓存,信号,admin后台
- Oracle em 此网站的安全证书存在问题
- Linux ip forward
- 由testcase数据之分析
- 2018.07.22 洛谷P1967 货车运输(kruskal重构树)
- 关于linux-centos7 安装完成git后npm突然无法使用问题处理
- 算法笔记_193:历届试题 连号区间数(Java)