[loj3339]美食家

令$f[i][j]$表示第$i$个时刻走到点$j$的最小时间,暴力的$dp$复杂度为$o(tm)$
如果没有限制,由于$w\le 5$,记录前5个时刻的状态即可求出当前状态,用矩阵乘法可优化到$o(n^{3}\log_{2}T)$
当$k\le 10$时,考虑特殊的转移只有10个位置,对于其他位置矩乘转移,这些位置特殊考虑,复杂度$o(n^{3}k\log_{2}T)$
用倍增预处理出矩阵的$2^{i}$次幂,直接用答案进行运算使一次乘法降为$o(n^{2})$,总复杂度即$o((n+k)n^2\log_{2}T)
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define oo 1e15
 5 struct mat{
 6     ll a[305][305];
 7 }a,o,aa,mi[31];
 8 struct fe{
 9     int t,k,w;
10 }b[205];
11 int n,m,t,k,x,y,z,flag,w[105];
12 ll s[305],ans[305];
13 bool cmp(fe x,fe y){
14     return x.t<y.t;
15 }
16 mat mul(mat &x,mat &y){
17     for(int i=1;i<=5*n;i++)
18         for(int j=1;j<=5*n;j++){
19             o.a[i][j]=-oo;
20             for(int k=1;k<=5*n;k++)o.a[i][j]=max(o.a[i][j],x.a[i][k]+y.a[k][j]);
21         }
22     return o;
23 }
24 void mul(mat &x){
25     memcpy(s,ans,sizeof(s));
26     for(int i=1;i<=5*n;i++){
27         ans[i]=-oo;
28         for(int j=1;j<=5*n;j++)ans[i]=max(ans[i],s[j]+x.a[j][i]);
29     }
30 }
31 void pow(int n){
32     for(int i=0;i<=30;i++)
33         if (n&(1<<i))mul(mi[i]);
34 }
35 int main(){
36     freopen("delicacy.in","r",stdin);
37     freopen("delicacy.out","w",stdout);
38     scanf("%d%d%d%d",&n,&m,&t,&k);
39     for(int i=1;i<=n;i++)scanf("%d",&w[i]);
40     for(int i=1;i<=5*n;i++)
41         for(int j=1;j<=5*n;j++)a.a[i][j]=-oo;
42     for(int i=1;i<=m;i++){
43         scanf("%d%d%d",&x,&y,&z);
44         a.a[(5-z)*n+x][4*n+y]=w[y];
45     }
46     for(int i=n+1;i<=5*n;i++)a.a[i][i-n]=0;
47     aa=a;
48     for(int i=1;i<=k;i++)scanf("%d%d%d",&b[i].t,&b[i].k,&b[i].w);
49     sort(b+1,b+k+1,cmp);
50     mi[0]=a;
51     for(int i=1;i<=30;i++)mi[i]=mul(mi[i-1],mi[i-1]);
52     for(int i=1;i<=5*n;i++)ans[i]=-oo;
53     ans[4*n+1]=0;
54     for(int i=1;i<=k;i++){
55         pow(b[i].t-b[i-1].t-1);
56         a=mi[0];
57         for(int j=1;j<=5*n;j++)a.a[j][4*n+b[i].k]+=b[i].w;
58         mul(a);
59     }
60     pow(t-b[k].t);
61     if (ans[4*n+1]<0)printf("-1\n");
62     else printf("%lld",ans[4*n+1]+w[1]);
63     return 0;
64 }
View Code

 

posted @ 2020-08-19 21:55  PYWBKTDA  阅读(105)  评论(0编辑  收藏  举报