2/11 矩阵快速幂+dp+二分

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2/11 矩阵快速幂+dp+二分相关的知识,希望对你有一定的参考价值。

矩阵快速幂模板题:
可解决数据规模很大,但有递推公式的式子

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll n,k;
struct Matrix

	static const int N=102;  //开设的矩阵
	ll a[N][N];
	Matrix(ll e=0)          //矩阵清0
	
		for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
            a[i][j]=e*(i==j);
	
	Matrix mul(Matrix A,Matrix B)   //矩阵的乘法运算   A*B
	
		Matrix ans(0);    //初始化全为0的矩阵
		for (int i=1;i<=n;i++)
        
			for (int j=1;j<=n;j++)
			
				for (int k=1;k<=n;k++)  
							//模拟乘法运算
					ans.a[i][j]=(ans.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
				
			
		
		return ans;  //返回
	
	Matrix ksm(Matrix A,ll b)
		Matrix ans(1);   //初始化全为1的矩阵
		while (b)
        
			if (b&1)ans=mul(ans,A);   //快速幂
			A=mul(A,A);
			b>>=1;
		
		return ans;
	
;
int main()

    scanf("%lld%lld",&n,&k);
	Matrix tmp;
    for(int i=1;i<=n;i++)
    
        for(int j=1;j<=n;j++)
            cin>>tmp.a[i][j];
    
    tmp=tmp.ksm(tmp,k);
    for(int i=1;i<=n;i++)
    
        for(int j=1;j<=n;j++)
            cout<<tmp.a[i][j]<<" ";
        cout<<endl;
    

    return 0;

https://www.luogu.com.cn/problem/P1103
难点还是在于
确定数组含义
and
设计状态转移方程

#include <bits/stdc++.h>

using namespace std;
const int mod=1e6+7;
const int inf=0x3f3f3f3f;
int f[105][105],n,k,m,a[105],minn=inf;
struct book

    int h,w;
e[105];
bool cmp(book e1,book e2)

    return e1.h<e2.h;

int main()

    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&e[i].h,&e[i].w);
    sort(e+1,e+n+1,cmp);
    memset(f,inf,sizeof(f));
    for(int i=1;i<=n;i++)
    
        f[i][1]=0;
    
    for(int i=2;i<=n;i++)    //表示要加入的是第几本书
    
        for(int j=1;j<i;j++)  //与前面第j本书相邻
        
            for(int len=2;len<=min(i,n-k);len++)  //目前选取的书数量
                f[i][len]=min(f[i][len],f[j][len-1]+abs(e[i].w-e[j].w));
        
    
    for(int i=n-k;i<=n;i++)
        minn=min(minn,f[i][n-k]);
    cout<<minn<<endl;
    return 0;

https://www.luogu.com.cn/problem/P1182
最大值最小

while(l<r)

    int mid=(l+r)>>1;
    if(check(mid))     //所分数量超过需要,返回1
         l=mid+1;
    else
         r=mid;

最小值最大:

while(l<r)

    int mid=(l+r+1)>>1;
    if(check(mid))     //所分数量小于需要,返回1
        r=mid-1;
    else
        l=mid;

#include <bits/stdc++.h>

using namespace std;
const int mod=1e6+7;
const int inf=0x3f3f3f3f;
int n,m,a[100005],l,r;
int check(int x)

    int sum=0,num=0;
    for(int i=1;i<=n;i++)
    
        if(sum+a[i]<=x)
            sum+=a[i];
        else
            sum=a[i],num++;
    
    return num>=m;   //分的数量大于题目要求数,说明x值小了

int main()

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    
        scanf("%d",&a[i]);
        l=max(l,a[i]);
        r+=a[i];
    
    while(l<r)            //最大值最小的模板
    
        int mid=(l+r)>>1;
        if(check(mid))
            l=mid+1;
        else
            r=mid;
    
    cout<<l<<endl;
    return 0;

以上是关于2/11 矩阵快速幂+dp+二分的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 2276 位运算矩阵快速幂

六省联考2017组合数问题 题解(矩阵快速幂优化DP)

poj 3233(矩阵快速幂)

HDU 5863 cjj's string game ( 16年多校10 G 题矩阵快速幂优化线性递推DP )

矩阵乘法加速图上问题专题总结

Codeforces Round #518 (Div. 1) Computer Game 倍增+矩阵快速幂