这个题很劲的,先贴代码,具体想法过程,一会再来写
用矩阵快速幂去实现了一个寻找最优解的过程
矩阵快速幂和dp的原理其实是类似的,通过对状态的压缩,减少时间复杂度
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<string.h>
#define LL long long
using namespace std;
const int mod = 1e9 + 7;
struct mat
{
LL m[20][20];
};
LL n,k;
mat res, pre, ret;
mat MatMul(mat a, mat b, LL len)
{
mat tmp;
memset(tmp.m,0,sizeof(tmp.m));
for(int i=0;i<=len;i++)
{
for(int j=0;j<=len;j++)
{
for(int k=0;k<=len;k++)
{
tmp.m[i][j] += a.m[i][k]%mod * b.m[k][j]%mod;
tmp.m[i][j] %= mod;
}
}
}
return tmp;
}
void print(mat tmp)
{
printf("*********************\n");
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
{
printf("%d ",tmp.m[i][j]);
}
printf("\n");
}
}
mat Quick(mat a ,LL k, LL len)
{
mat tmp;
memset(tmp.m,0,sizeof(tmp.m));
for(int i=0;i<=len;i++)
{
tmp.m[i][i] = 1;
}
while(k)
{
if(k%2 == 1)
{
tmp = MatMul(a,tmp,len);
k -= 1;
}
else
{
a = MatMul(a,a,len);
k >>= 1;
}
//print(tmp);
}
return tmp;
}
int main()
{
while(~scanf("%lld%lld",&n,&k))
{
memset(res.m,0,sizeof(res.m));
memset(pre.m,0,sizeof(pre.m));
memset(ret.m,0,sizeof(ret.m));
for(int i=0;i<16;i++)
{
for(int j=i-1;j<i+2 && j<16;j++)
{
if(j >= 0 && j<16)
{
res.m[i][j] = 1;
}
}
}
pre.m[0][0] = 1;
for(int i=0;i<n;i++)
{
LL l,r,y;
scanf("%lld%lld%lld",&l,&r,&y);
if(r>k) r = k;
ret = Quick(res,r-l,y);
//print(ret);
for(int i=y+1;i<16;i++) pre.m[i][0] = 0;
ret = MatMul(ret,pre,y);
for(int i=0;i<=y;i++)
{
pre.m[i][0] = ret.m[i][0];
}
}
printf("%lld\n",pre.m[0][0]);
}
}