传送门:QAQQAQ

完了完了NOI签到题全班打不出来,真就全部成为时代的眼泪了。。。

首先$O(mT)$的$dp$显然,然后因为$T$很大$w$很小矩阵快速幂显然,但是有$k=200$卡不过去。

然后因为行向量乘上转移矩阵是$O(n^{2})$的,所以我们枚举的$k$时只用行向量乘上转移矩阵,转移矩阵的自乘放在外面倍增预处理,这样复杂度是$O(n^{2}*k*log(V)+(n^{3}*log(V)))$,开了O2非常稳

所以最近两道几乎正解的矩乘都没打出来。。一道倍增预处理转移矩阵优化,一道先DFT转点值再快速幂而不是每次快速幂用FFT优化来降复杂度。。

菜是原罪。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const ll inf=(ll)1e15;
#define mk make_pair
void checkmin(ll &x,ll y){if(x>y) x=y;}
void checkmax(ll &x,ll y){if(x<y) x=y;}
const int N=2010;
vector<pii> v[N],G[N];
int t[N],X[N],Y[N],c[N];
int n,m,T,k;
struct Edge
{
int from,to,cost;
}E[N]; void init()
{
scanf("%d%d%d%d",&n,&m,&T,&k);
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&E[i].from,&E[i].to,&E[i].cost);
v[E[i].from].push_back(mk(E[i].to,E[i].cost));
G[E[i].to].push_back(mk(E[i].from,E[i].cost));
}
for(int i=1;i<=k;i++) scanf("%d%d%d",&t[i],&X[i],&Y[i]);
} namespace solver1{
ll dp[52600][55]; int a[52600][55];
void init()
{
memset(a,0,sizeof(a));
for(int i=1;i<=k;i++) a[t[i]][X[i]]=Y[i];
}
void main()
{
init();
for(int i=0;i<=T;i++)
for(int j=1;j<=n;j++) dp[i][j]=-inf;
dp[0][1]=c[1];
for(int i=1;i<=T;i++)
{
for(int j=1;j<=n;j++)
{
for(int p=0;p<(int)G[j].size();p++)
{
int to=G[j][p].first,w=G[j][p].second;
if(i<w) continue;
checkmax(dp[i][j],dp[i-w][to]+c[j]);
}
}
for(int j=1;j<=n;j++) dp[i][j]+=a[i][j];
}
if(dp[T][1]<=0) puts("-1");
else printf("%lld\n",dp[T][1]);
}
} struct matrix{
ll a[255][255];
int n,m;
matrix(){}
matrix(int n,int m):n(n),m(m){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) a[i][j]=-inf;
}
}; matrix operator * (matrix A,matrix B)
{
matrix C(A.n,B.m);
for(int i=1;i<=C.n;i++)
{
for(int k=1;k<=A.m;k++)
{
if(A.a[i][k]==-inf) continue;
for(int j=1;j<=C.m;j++)
checkmax(C.a[i][j],A.a[i][k]+B.a[k][j]);
}
}
return C;
} struct LI{
int t,x,y;
LI(){}
LI(int t,int x,int y):t(t),x(x),y(y){}
bool operator < (const LI &rhs) const{
return t<rhs.t;
}
}limit[N]; matrix Base[31];
void Qpow(matrix &A,int y)
{
matrix ret(A.n,A.m);
for(int i=1;i<=A.n;i++) ret.a[i][i]=0;
for(int i=30;i>=0;i--)
{
if((1<<i)<=y) y-=(1<<i),A=A*Base[i];
}
} namespace solver2{
ll dp1[7][55]; int a[7][55];
void init()
{
memset(a,0,sizeof(a));
for(int i=1;i<=k;i++)
if(t[i]<=5) a[t[i]][X[i]]=Y[i];
}
void build()
{
init();
for(int i=0;i<=5;i++)
for(int j=1;j<=n;j++) dp1[i][j]=-inf;
dp1[0][1]=c[1];
for(int i=1;i<=5;i++)
{
for(int j=1;j<=m;j++)
{
int u=E[j].from,to=E[j].to,w=E[j].cost;
if(i<E[j].cost) continue;
if(dp1[i-w][u]==-inf) continue;
checkmax(dp1[i][to],dp1[i-w][u]+c[to]);
}
for(int j=1;j<=n;j++) dp1[i][j]+=a[i][j];
}
}
void main()
{
build();
int TMP=0;
for(int i=1;i<=k;i++)
{
if(t[i]<=5) i--,k--,TMP++;
limit[i]=LI(t[i+TMP],X[i+TMP],Y[i+TMP]);
}
sort(limit+1,limit+k+1);
matrix A(1,n*5);
for(int i=1;i<=5;i++)
{
for(int j=1;j<=n;j++) A.a[1][(i-1)*n+j]=dp1[i][j];
}
//print(A);
for(int i=0;i<=30;i++)
{
Base[i].m=Base[i].n=5*n;
for(int j=1;j<=5*n;j++)
{
for(int t=1;t<=5*n;t++)
{
Base[i].a[j][t]=-inf;
}
}
}
for(int j=1;j<=n*4;j++) Base[0].a[j+n][j]=0;
for(int i=1;i<=m;i++)
{
int u=E[i].from,to=E[i].to,w=E[i].cost;
int from=(5-w)*n+u; to=4*n+to;
Base[0].a[from][to]=c[E[i].to];
}
//print(Base);
for(int i=1;i<=30;i++) Base[i]=Base[i-1]*Base[i-1]; T-=5;
for(int i=1;i<=k;i++) limit[i].t-=5;
int now=0;
for(int i=1;i<=k;i++)
{
int pos=limit[i].t;
Qpow(A,pos-now);
now=pos;
if(A.a[1][4*n+limit[i].x]==-inf) continue;
else A.a[1][4*n+limit[i].x]+=limit[i].y;
} Qpow(A,T-now);
if(A.a[1][4*n+1]<=0) puts("-1");
else printf("%lld\n",A.a[1][4*n+1]);
}
} namespace solver3{
int dis[N],vis[N];
ll tot=0;
void dfs(int u){
if(vis[u]) return;
vis[u]=1;
for(int i=0;i<(int)v[u].size();i++)
{
int to=v[u][i].first,w=v[u][i].second;
dis[to]=dis[u]+w;
dfs(to);
}
}
void main()
{
memset(vis,0,sizeof(vis)); dis[1]=0;
dfs(1);
if(T%dis[1]!=0)
{
puts("-1");
return;
}
ll ans=c[1];
for(int i=1;i<=k;i++)
{
if((t[i]-dis[X[i]])%dis[1]==0) ans+=Y[i];
}
for(int i=1;i<=n;i++) tot+=c[i];
ans+=T/dis[1]*tot;
printf("%lld\n",ans);
}
} bool iscircle()
{
if(n!=m) return 0;
for(int i=1;i<=m;i++)
{
if(E[i].to!=E[i].from%n+1) return 0;
}
return 1;
} void solve()
{
if(T<=52600)
{
solver1::main();
return;
}
if(iscircle())
{
solver3::main();
return;
}
solver2::main();
return;
} int main()
{
//freopen("delicacy.in","r",stdin);
//freopen("delicacy.out","w",stdout);
init();
solve();
fclose(stdin); fclose(stdout);
return 0;
}

NOI2020D1T1美食家的更多相关文章

  1. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

    1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][S ...

  2. [BZOJ1691][Usaco2007 Dec]挑剔的美食家

    [BZOJ1691][Usaco2007 Dec]挑剔的美食家 试题描述 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了. ...

  3. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家( 平衡树 )

    按鲜嫩程度排个序, 从大到小处理, 用平衡树维护价值 ---------------------------------------------------------------------- #i ...

  4. BZOJ_1691_[Usaco2007 Dec]挑剔的美食家_贪心

    BZOJ_1691_[Usaco2007 Dec]挑剔的美食家_贪心 题意: 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返 ...

  5. 51nod 挑剔的美食家

    挑剔的美食家    基准时间限制:1 秒 空间限制:131072 KB 分值: 5 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一 ...

  6. Java实现 蓝桥杯VIP 算法提高 聪明的美食家

    算法提高 聪明的美食家 时间限制:1.0s 内存限制:256.0MB 问题描述 如果有人认为吃东西只需要嘴巴,那就错了. 都知道舌头有这么一个特性,"由简入奢易,由奢如简难"(据好 ...

  7. 【NOI2020】美食家(矩阵)

    Description 给定一张有向图,\(n\) 个顶点,\(m\) 条边.第 \(i\) 条边从 \(u_i\) 到 \(v_i\),走完该边的用时为 \(w_i\).每一个点有一个价值 \(c\ ...

  8. [XIN算法应用]NOI2020美食家

    XIN(\(updated 2021.6.4\)) 对于很多很多的题目,发现自己并不会之后,往往会直接冲上一个XIN队算法,然而,这样 \(\huge{\text{鲁莽}}\) 的行为只能获得 TLE ...

  9. BZOJ1691: [Usaco2007 Dec]挑剔的美食家

    传送门: 一句话题解:贪心+treap 好几天前刚学的treap,然后真到了考treap又写不出来,这么辣鸡还搞什么OI 先按$A_i$递减排序,然后把$C_i$也递减排序,然后用一个指针指向$M$序 ...

随机推荐

  1. IOS 数据储存

    IOS 数据存储 ios数据存储包括以下几种存储机制: 属性列表 对象归档 SQLite3 CoreData AppSettings 普通文件存储 1.属性列表 // //  Persistence1 ...

  2. dirsearch下载与简单实用

    下载 下载地址   我的电脑是Windows,而且我也有python3.6的环境,所以我是直接clone到本地就能使用了.   命令的提示在上面的下载地址里就有,这里给个最简单的命令(脚本小子专属,我 ...

  3. GIT 保存日志并建立自己的分支

    以下是我个人在工作中对git的愚见全是大白话说明.也是我踩坑记录吧,防止下次再次踩坑. 再已有的dev(开发分支)新建自己的分支 (featuer)在更新到gitlab 仓库中的过程. 首先要有大致的 ...

  4. vmware 安装tools

    kali linux 更换成国内源后 安装tools命令 apt install open-vm-tools-desktop fuse -y 需重启  reboot

  5. 【换根DP】小奇的仓库

    题目背景 小奇采的矿实在太多了,它准备在喵星系建个矿石仓库.令它无语的是,喵星系的货运飞船引擎还停留在上元时代! 题目内容 喵星系有\(n\)个星球,星球以及星球间的航线形成一棵树. 从星球\(a\) ...

  6. 【模拟】CF 796C Bank Hacking

    题目大意 洛谷链接 给定一棵带点权树,选出一个最佳的根节点,使得根节点的点权不变,它的儿子点权加1,其余点点权加2,并使最大点权最小,输出这个最小的最大点权. 其他见链接(懒). PS:原题面很不好总 ...

  7. 洛谷 CF1012C Hills(动态规划)

    题目大意: 有几座山,如果一座山左右两边的山比它矮,那么可以在这个山上建房子,你有一台挖掘机,每天可以挖一座山一米,问你需要花多少代价可以分别盖1.2.3--座房子.(给出山的数量,以及每座山的高度) ...

  8. swoft配置连接池

    bean.php 'db' => [ 'class' => Database::class, 'dsn' => 'mysql:dbname=test;host=127.0.0.1', ...

  9. linux(centos8):禁用selinux(临时关闭/永久关闭)

    一,selinux的用途 1,什么是selinux SELinux:即安全增强型 Linux(Security-Enhanced Linux) 它是一个 Linux 内核模块,也是 Linux 的一个 ...

  10. vue学习笔记(一)---- vue指令( v-bind 属性绑定 )

    看栗子: <body> <div id="app"> <input type="button" value="按钮&qu ...