• [被踩计划] 题解 [NOI2020]美食家


    为什么叫被踩记录呢?因为感觉自己之前真的是太菜了,打算把之前联赛等考过的题目做一做,看看自已以前有多菜,所以取名叫被踩记录。

    题目链接

    题目分析

    发现 (T) 很大而 (n) 很小,显然可以使用矩阵快速幂来优化 dp ,但是有几个问题。

    首先是 (w) 并不都为 (1) ,考虑拆点,把一个点拆成 (max(w)) 个点,如果 (u)(v) 连了长度为 (w) 的边,那么就从 (u) 拆出来的第 (w) 个点向 (v) 连边。

    然后就是有美食节,这个很简单处理,把所有美食节按时间排序,然后从早到晚依次处理每次美食节,美食节之间的跳跃就用矩阵快速幂优化就行了。

    dp 状态和转移就不用说了。

    参考代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ch() getchar()
    #define pc(x) putchar(x)
    using namespace std;
    template<typename T>void read(T&x){
    	static char c;static int f;
    	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
    	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
    }
    template<typename T>void write(T x){
    	static char q[65];int cnt=0;
    	if(x<0)pc('-'),x=-x;
    	q[++cnt]=x%10,x/=10;
    	while(x)
    		q[++cnt]=x%10,x/=10;
    	while(cnt)pc(q[cnt--]+'0');
    }
    const int maxn=255,maxk=205;
    int N;
    struct Matrix{
    	long long v[maxn][maxn];
    	Matrix(){
    		memset(v,-0x3f,sizeof v);
    	}
    	Matrix operator * (const Matrix o)const{
    		Matrix re;
    		for(int i=1;i<=N;++i)
    			for(int j=1;j<=N;++j)
    				for(int k=1;k<=N;++k)
    					re.v[i][j]=max(re.v[i][j],v[i][k]+o.v[k][j]);
    		return re;
    	}
    }Base[32];
    struct Qu{
    	int t,x,y;
    	Qu(int t=0,int x=0,int y=0):
    		t(t),x(x),y(y){}
    	bool operator < (const Qu o)const{
    		return t<o.t;
    	}
    }Q[maxk];
    long long dp[maxn],tmp[maxn],c[maxn];
    int main(){
    	int n,m,T,k;
    	read(n),read(m),read(T),read(k);N=n*5;
    	for(int i=1;i<=n;++i){
    		read(c[i]);
    		for(int j=1;j<=4;++j)
    			Base[0].v[i+(j-1)*n][i+j*n]=0;
    	}
    	for(int i=1;i<=m;++i){
    		int u,v,w;
    		read(u),read(v),read(w);u+=(w-1)*n;
    		Base[0].v[u][v]=c[v];
    	}
    	for(int i=1;i<32;++i)Base[i]=Base[i-1]*Base[i-1];
    	for(int i=1;i<=k;++i)read(Q[i].t),read(Q[i].x),read(Q[i].y);++k;Q[k].t=T;Q[k].x=1;Q[k].y=0;
    	memset(dp,-0x3f,sizeof dp);dp[1]=c[1];int tim=0;sort(Q+1,Q+k+1);
    	for(int s=1;s<=k;++s){
    		for(int t=Q[s].t-tim,cn=0;t;t>>=1,++cn){
    			if(t&1){
    				memset(tmp,-0x3f,sizeof tmp);
    				for(int i=1;i<=N;++i){
    					for(int j=1;j<=N;++j){
    						tmp[i]=max(tmp[i],dp[j]+Base[cn].v[j][i]);
    					}
    				}
    				memcpy(dp,tmp,sizeof tmp);
    			}
    		}
    		dp[Q[s].x]+=Q[s].y;
    		tim=Q[s].t;
    	}
    	if(dp[1]>=0)write(dp[1]),pc('
    ');
    	else puts("-1");
    	return 0;
    }
    
    
  • 相关阅读:
    查询本地ip以及ip地址库查询
    python在linux中import cv2问题
    drf安装与APIView初步分析
    CBV源码分析
    RESTful规范
    Vue路由vue-router
    Django之ModelForm组件
    django路由的反向解析
    django路由系统及分发路由的本质
    前端以及django零碎补充
  • 原文地址:https://www.cnblogs.com/lsq147/p/13746910.html
Copyright © 2020-2023  润新知