HDU 5863 cjj's string game(矩阵dp)
2016-08-19 21:40
441 查看
转载声明:http://blog.csdn.net/lqybzx/article/details/52245704
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5863
题意:
给你k个字符, 然后要组成2个最长公共子串为最大为m的方案数,其中长度为n.
个人感想:
那时在做这题的时候,我有想过用dp,可是发现n太大,我根本不知道该怎么dp,我记得我也做过一个类似的dp,反正就是dp[i][j] ,就是长度为i,以i结尾长度为j的相同的方案数..反正也是类似的,但是我觉得,不可能吧.而且他还得恰好长度为m,..这我尼玛真的不会了..我居然去找规律,,,然后GG..
之后看了一下题解,我懵逼了,
我们其实可以这样
长度为n的公共最长子序列至多为m的方案数-长度为n的公共最长子序列至多为m-1的方案数 =长度为n的公共最长子序列恰好为m的方案数
..顿时感觉自己好尼玛蠢啊… 题还是撸得不多啊.. 总觉得dp就把自己卡死… dp算法真难掌握.
其实我们再想想,如果求既然求dp的话,那么我们只要知道前m条记录,然后来滚动dp就行了,难道不是吗?这个就意会一下咯..
说说dp方程,
dp[i][j]:长度为i,(i-j+1 -> i)都是和第2个对应字符位置的字符有j个相同的方案数.
那么我们就很容易推倒出dp方程了..
dp[i][j]=dp[i-1][j-1]*k:第i位也相同的方案数.
dp[i][0]=Σ (0->m)( j ) dp[i-1][j] 第i位开始不相同的方案数.
这dp 真的很好理解,静下心来想就好了,可是因为n实在是太大了.. 别人说一看到这样的n,必定是需要矩阵来优化加速的.。。OK你们有道理..我是不懂,但我得记住啊..
那么这个矩阵得怎么画呢,其实我一开始看他们的程序,我一脸懵逼,,因为我真不会,对矩阵这东西就是个渣.好吧不说这些.这是我感觉出来的. 矩阵就应该这样画.
画得丑一点,,别介意,
一看,我曹,, 这不就是《挑战程序设计竞赛》,那个斐波那契公式的推倒吗,只要中间那块用快速幂,不就是答案了..这真是一目了然,,直接可以写代码了, 我觉得看到这里,你也不用看我的代码了..
分析:矩阵dp.
AC代码:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5863
题意:
给你k个字符, 然后要组成2个最长公共子串为最大为m的方案数,其中长度为n.
个人感想:
那时在做这题的时候,我有想过用dp,可是发现n太大,我根本不知道该怎么dp,我记得我也做过一个类似的dp,反正就是dp[i][j] ,就是长度为i,以i结尾长度为j的相同的方案数..反正也是类似的,但是我觉得,不可能吧.而且他还得恰好长度为m,..这我尼玛真的不会了..我居然去找规律,,,然后GG..
之后看了一下题解,我懵逼了,
我们其实可以这样
长度为n的公共最长子序列至多为m的方案数-长度为n的公共最长子序列至多为m-1的方案数 =长度为n的公共最长子序列恰好为m的方案数
..顿时感觉自己好尼玛蠢啊… 题还是撸得不多啊.. 总觉得dp就把自己卡死… dp算法真难掌握.
其实我们再想想,如果求既然求dp的话,那么我们只要知道前m条记录,然后来滚动dp就行了,难道不是吗?这个就意会一下咯..
说说dp方程,
dp[i][j]:长度为i,(i-j+1 -> i)都是和第2个对应字符位置的字符有j个相同的方案数.
那么我们就很容易推倒出dp方程了..
dp[i][j]=dp[i-1][j-1]*k:第i位也相同的方案数.
dp[i][0]=Σ (0->m)( j ) dp[i-1][j] 第i位开始不相同的方案数.
这dp 真的很好理解,静下心来想就好了,可是因为n实在是太大了.. 别人说一看到这样的n,必定是需要矩阵来优化加速的.。。OK你们有道理..我是不懂,但我得记住啊..
那么这个矩阵得怎么画呢,其实我一开始看他们的程序,我一脸懵逼,,因为我真不会,对矩阵这东西就是个渣.好吧不说这些.这是我感觉出来的. 矩阵就应该这样画.
画得丑一点,,别介意,
一看,我曹,, 这不就是《挑战程序设计竞赛》,那个斐波那契公式的推倒吗,只要中间那块用快速幂,不就是答案了..这真是一目了然,,直接可以写代码了, 我觉得看到这里,你也不用看我的代码了..
分析:矩阵dp.
AC代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define lson 2*k #define rson 2*k+1 typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1e5+10; int Scan()//读入整数外挂. { int res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } void Out(int a) //输出外挂 { if(a>9) Out(a/10); putchar(a%10+'0'); } typedef vector<ll> vec; typedef vector<vec> mat; const ll M=1000000007; int n,m,k; mat mul(mat &A,mat &B) { mat C(A.size(),vec(B[0].size())); for(int i=0;i<A.size();i++) { for(int k=0;k<B.size();k++) { for(int j=0;j<B[0].size();j++) { C[i][j]=(C[i][j]+A[i][k] * B[k][j])%M; } } } return C; } mat pow(mat A, ll n) { mat B(A.size(),vec(A.size())); for(int i=0;i<A.size();i++) { B[i][i]=1; } while(n>0) { if(n&1) B=mul(B,A); A=mul(A,A); n>>=1; } return B; } ll solve(int m) { mat A((m+1),vec(m+1)); for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) A[i][j]=0; for(int i=0;i<=m;i++) A[i][0]=(ll)k*(k-1); for(int i=0;i<m;i++) A[i][i+1]=(ll)k; A=pow(A,n); ll ans=0; for(int j=0;j<=m;j++) { ans=(ans+A[0][j])%M; } return ans; } int main() { #ifndef ONLINE_JUDGE freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); ll ans=solve(m)-solve(m-1); if(ans<0) ans+=M; printf("%I64d\n",ans); } return 0; }
相关文章推荐
- HDU 5863 cjj's string game(矩阵优化DP)
- HDU 5863 cjj's string game 快速幂 dp
- HDU 5863 cjj's string game(矩阵快速幂)
- HDU 5863 cjj's string game(矩阵快速幂)
- Hdu-5863 cjj's string game(矩阵快速幂)
- HDU 5863 cjj's string game(矩阵快速幂) ★
- HDU - 5863 cjj's string game 矩阵快速幂
- 矩阵快速幂,动态规划(cjj's string game,HDU 5863)
- HDU 5863 cjj's string game(dp+矩阵快速幂)
- HDU - 5863 - cjj's string game (递推)
- HDU 5860 cjj's string game
- HDU 5863 cjj's string game
- HDU 4681 String(2013多校8 1006题 DP)
- hdu 4576(简单概率dp | 矩阵优化)
- HDU 4681 String(DP 最长公共子系列)
- hdu 4681 String(dp)
- HDU 4681 String(DP)
- HDU 4616 Game (搜索)、(树形dp)
- 【解题报告】HDU 4616 Game - 树形dp
- HDU-4616 Game 树形DP