[XIN算法应用]NOI2020美食家
XIN(\(updated 2021.6.4\))
对于很多很多的题目,发现自己并不会之后,往往会直接冲上一个XIN队算法,然而,这样 \(\huge{\text{鲁莽}}\) 的行为只能获得 TLE,所以,我们要考虑如何拿到最大的部分分值。
noi 2020 美食家
看完题目之后,发现这个题目的范围很鬼畜,似乎只能用 \(\mathcal O(log_2T)\) 的复杂的过去。。。。
之后大脑空白 \(1e9\) 分钟。。。。。。。。。。。。。。。。。
之后目光转向 1 ~ 8 的测试点,发现似乎可以用 \(\mathcal O(nT)\) 的复杂度拿到,所以开始考虑部分分数。
如果使用以往的XIN队算法,那么预测应该最多只拿到 4 个测试点,所以我们就要考虑非纯暴力解法
首先我们要推出方程:怎么推呢,用 \(\huge{\text{杠哥大定理}}\)。
所以方程就是:
\]
之后就可以使用 \(\huge{\text{记忆化}}\)来解决
int xin_team(int x,int tim)
{
if(f[x][tim]) return f[x][tim];
if(x == 1 and !tim)
{ok = true;return c[x];}
else if(tim < 0)
return 0x7f7f7f7f7f7f7f7f;
int maxx = -0x7f7f7f7f7f7f7f7f;
for(register int i=0;i<link[x].size();++i)
{
register int y = link[x][i].pos;
int zhuan = xin_team(y,tim - link[x][i].val);
if(zhuan < 0x7f7f7f7f7f7f7f7f)
maxx = max(maxx,zhuan);
}
for(register int i=1;i<=k;++i)
if(x == a[i].x and tim == a[i].t)
{f[x][tim] += a[i].y;break;}
f[x][tim] += maxx + c[x];
// cout<<"x = "<<x<<" time = "<<tim<<endl;
return f[x][tim];
}
这就是 核心代码
复杂度 \(\mathcal O(nT)\) 还算比较 \(\color{red}{\text{优秀}}\)
之后就可以拿到 \(40pts\) 了!
\(code_{tot}:\)
#include<cmath>
#include<queue>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
#define m(c,num) memset(c,num,sizeof c)
#define INF 0x7f7f7f7f
#define debug cout<<"debug"<<endl
#define freopen eat = freopen
#define scanf a14 = scanf
namespace xin_io
{
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; FILE *eat; int a14;
inline void openfile() {freopen("t.txt","r",stdin);}
inline void outfile() {freopen("o.txt","w",stdout);}
inline int get()
{
int s = 0,f = 1;register char ch = gc();
while(!isdigit(ch))
{if(ch == '-') f = -1;ch = gc();}
while(isdigit(ch))
{s = s * 10 + ch - '0'; ch = gc();}
return s * f;
}
}
static const int maxn = 201,maxt = 52502;
using namespace xin_io;
namespace xin
{
class xin_edge{public:int w,next,ver;}edge[maxn];
class xin_data{public:int pos,val;xin_data(int x,int y):pos(x),val(y){}};
class xin_food{public:int t,x,y;}a[maxn<<2];
int head[maxn],zhi = 0;
inline void add(int x,int y,int z)
{edge[++zhi].ver = y;edge[zhi].w = z;edge[zhi].next = head[x]; head[x] = zhi;}
int c[maxn];
int n,m,t,k;
bool ok = false;
vector <xin_data> link[maxn];
int f[maxn][maxt];
int xin_team(int x,int tim)
{
if(f[x][tim]) return f[x][tim];
if(x == 1 and !tim)
{ok = true;return c[x];}
else if(tim < 0)
return 0x7f7f7f7f7f7f7f7f;
int maxx = -0x7f7f7f7f7f7f7f7f;
for(register int i=0;i<link[x].size();++i)
{
register int y = link[x][i].pos;
int zhuan = xin_team(y,tim - link[x][i].val);
if(zhuan < 0x7f7f7f7f7f7f7f7f)
maxx = max(maxx,zhuan);
}
for(register int i=1;i<=k;++i)
if(x == a[i].x and tim == a[i].t)
{f[x][tim] += a[i].y;break;}
f[x][tim] += maxx + c[x];
// cout<<"x = "<<x<<" time = "<<tim<<endl;
return f[x][tim];
}
inline short main()
{
#ifndef ONLINE_JUDGE
openfile();
#endif
n = get(); m = get(); t = get(); k = get();
// memset(f,128,sizeof(f));
if(t > 52501) {cout<<-1<<endl;return 0;}
for(register int i=1;i<=n;++i) c[i] = get();
for(register int i=1;i<=m;++i)
{register int x = get(),y = get(),z = get();add(x,y,z),link[y].push_back(xin_data(x,z));}
for(register int i=1;i<=k;++i) a[i].t = get(),a[i].x = get(),a[i].y = get();
int ans = xin_team(1,t);
if(ok)
cout<<ans<<endl;
else
cout<<-1<<endl;
return 0;
}
}
signed main() {return xin::main();}
[XIN算法应用]NOI2020美食家的更多相关文章
- [NOI2020]美食家 题解
题意分析 给出一个带权有向图,要求从节点 $1$ 出发,经过恰好 $T$ 的边权和,回到节点 $1$ ,求可经过的最大点权和.特别地,经过的边权和达到部分特殊数时,会有某个点的点权发生改变. 思路分析 ...
- P6772 [NOI2020]美食家
题目大意 给你一个 \(n\) 个点,\(m\) 条边的有向图,每条边有一个权值 \(w_i\) ,每个节点有一个权值 \(a_i\) . 你从节点 \(1\) 出发,每经过一个节点就可以获得该点的权 ...
- [NOI2020] 美食家
很好,自己会做NOI签到题了,去年只要会这题,再多打点暴力,\(Ag\)到手,希望今年\(NOI\)同步赛过\(Ag\)线吧,得有点拿得出手的成绩证明啊. 考虑\(T\)非常大,\(n\)又很小. 想 ...
- 洛谷 P6772 - [NOI2020]美食家(广义矩阵快速幂)
题面传送门 题意: 有一张 \(n\) 个点 \(m\) 条边的有向图,第 \(0\) 天的时候你在 \(1\) 号城市,第 \(T\) 天的时候你要回到 \(1\) 号城市. 每条边上的边权表示从城 ...
- XIN队算法
XIN队算法 注:名称由莫队算法改编而来 从luogu搬过来了... \(newly\;upd:2021.7.8\) \(newly\;upd:2021.6.6\) OI至高算法,只要XIN队算法打满 ...
- 【NOI2020】美食家(矩阵)
Description 给定一张有向图,\(n\) 个顶点,\(m\) 条边.第 \(i\) 条边从 \(u_i\) 到 \(v_i\),走完该边的用时为 \(w_i\).每一个点有一个价值 \(c\ ...
- [考试总结]noip模拟11
菜 这次考试又是骗了一堆分数... 然而其实一个正解都没写... \(T1\) 的方法说实话确实不是很正统.... 然而却 \(A\) 了... 在打完 \(T1\) 后拍了老长时间... 然后就耽搁 ...
- 启xin宝app的token算法破解——token分析篇(三)
前两篇文章分析该APP的抓包.的逆向: 启xin宝app的token算法破解--抓包分析篇(一) 启xin宝app的token算法破解--逆向篇(二) 本篇就将对token静态分析,其实很简单就可以搞 ...
- 启xin宝app的token算法破解——frida篇(四)
前两篇文章分析该APP的抓包.的逆向: 启xin宝app的token算法破解--抓包分析篇(一) 启xin宝app的token算法破解--逆向篇(二) 启xin宝app的token算法破解--toke ...
随机推荐
- QT Dialog模态与非模态
模态 // 创建对话框窗口 TestDialog* dlg = new TestDialog(this); // 阻塞程序的运行 dlg->exec(); 这样的话,当运行对话窗口的时候,会阻塞 ...
- WizTree——一个扫描快似Everything的硬盘空间分析工具
虽然我平时用的主要是Linux,但是由于实际环境是win10,对于磁盘资源的控制,我主要是通过Windows自带的文件资源管理器来查看的,但是显然这个工具不够直观.于是,我也被安利过SpaceSnif ...
- 『动善时』JMeter基础 — 44、JMeter对数据库的更新操作
目录 1.执行一条insert语句 2.insert语句实现参数化 3.一次执行多条insert语句 4.使用Beanshell生成加密数据示例 (1)测试计划内包含的元件 (2)JDBC连接配置组件 ...
- 浅谈.Net Core中使用Autofac替换自带的DI容器
为什么叫 浅谈 呢?就是字面上的意思,讲得比较浅,又不是不能用(这样是不对的)!!! Aufofac大家都不陌生了,说是.Net生态下最优秀的IOC框架那是一点都过分.用的人多了,使用教程也十分丰富, ...
- 为什么excel里面有的数据用CTRL+F,搜索搜不到?
- Java字符串比较(3种方法)以及对比 C++ 时的注意项
字符串比较是常见的操作,包括比较相等.比较大小.比较前缀和后缀串等.在 Java 中,比较字符串的常用方法有 3 个:equals() 方法.equalsIgnoreCase() 方法. compar ...
- C++中封装和继承的访问权限
众所周知,C++面向对象的三大特性为:封装,继承和多态.下面我们就先对封装做一些简单的了解.封装是通过C++中的类来完成的,类是一种将抽象转换为用户定义类型的工具.类的定义如下: class circ ...
- C#调用JAVA(二)调用方法
上期我们创建了jar包并放到了unity中,那么我们继续 如果您还没有看上一期请先看上一期,这是链接 C#调用JAVA(一)制作jar包 - 执著GodShadow - 博客园 (cnblogs.co ...
- 柔性数组(Redis源码学习)
柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...
- 【spring源码系列】之【Bean的属性赋值】
每次进入源码的世界,就像完成一场奇妙的旅行! 1. 属性赋值概述 上一篇讲述了bean实例化中的创建实例过程,实例化后就需要对类中的属性进行依赖注入操作,本篇将重点分析属性赋值相关流程.其中属性赋值, ...