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+二分的主要内容,如果未能解决你的问题,请参考以下文章