NOIp2018集训test-9-23
这个NOI模拟题怕是比你们的NOIp模拟题要简单哦。。
友好的生物
应该是一道简单题,但是机房只有辉神一个人想到正解似乎。
被我kd-tree水过去了(这不是kd-tree的裸题吗???(不是))
//Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
#define inf 1e18
const int N=;
using namespace std;
typedef long long LL;
typedef double db;
int n,K,D;
LL C[],ans; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int d[];
friend bool operator <(const node&A,const node&B) {
return A.d[D]<B.d[D];
}
}p[N],q[N],T; void get_min(int &x,int y) { if(x>y) x=y; }
void get_max(int &x,int y) { if(x<y) x=y; } int rt,ch[N][],dt[N][][];
#define lc ch[x][0]
#define rc ch[x][1]
#define mid ((l+r)>>1)
void update(int x,int l,int r) {
For(i,,K-) dt[x][i][]=dt[x][i][]=p[x].d[i];
if(lc) For(i,,K-) {
get_min(dt[x][i][],dt[lc][i][]);
get_max(dt[x][i][],dt[lc][i][]);
}
if(rc) For(i,,K-) {
get_min(dt[x][i][],dt[rc][i][]);
get_max(dt[x][i][],dt[rc][i][]);
}
} int build(int l,int r,int k) {
if(l>r) return ;
D=k;
sort(p+l,p+r+);
int x=((l+r)>>);
lc=build(l,x-,(k+)%K);
rc=build(x+,r,(k+)%K);
update(x,l,r);
return x;
} void get_ans(int x) {
LL rs=;
For(i,,K-) rs+=abs(p[x].d[i]-T.d[i])*C[i];
rs-=abs(p[x].d[K-]-T.d[K-])*C[K-];
ans=max(ans,rs);
} LL guess_min(int x) {
LL rs=;
For(i,,K-) {
if(dt[x][i][]<=T.d[i]&&dt[x][i][]>=T.d[i]) continue;
if(T.d[i]<dt[x][i][]) rs+=(dt[x][i][]-T.d[i])*C[i];
else rs+=(T.d[i]-dt[x][i][])*C[i];
}
rs-=max(abs(T.d[K-]-dt[x][K-][]),abs(T.d[K-]-dt[x][K-][]))*C[K-];
return rs;
} LL guess_max(int x) {
if(!x) return -inf;
LL rs=;
For(i,,K-) {
rs+=max(abs(T.d[i]-dt[x][i][]),abs(T.d[i]-dt[x][i][]))*C[i];
}
if(T.d[K-]<dt[x][K-][]) rs-=(dt[x][K-][]-T.d[K-])*C[K-];
else if(T.d[K-]>dt[x][K-][]) rs-=(T.d[K-]-dt[x][K-][])*C[K-];
return rs;
} void qry(int x,int l,int r,int k) {
if(!x||l>r) return ;
get_ans(x);
LL lg=guess_max(lc);
LL rg=guess_max(rc);
if(lg<=ans&&rg<=ans) return ;
if(lg>=rg) {
qry(lc,l,mid-,(k+)%K);
if(rg>ans) qry(rc,mid+,r,(k+)%K);
}
else {
qry(rc,mid+,r,(k+)%K);
if(lg>ans) qry(lc,l,mid-,(k+)%K);
}
} #define ANS
int main() {
#ifdef ANS
freopen("species.in","r",stdin);
freopen("species.out","w",stdout);
#endif
read(n); read(K);
For(i,,K-) read(C[i]);
For(i,,n) {
For(j,,K-) read(p[i].d[j]);
q[i]=p[i];
}
ans=-inf;
rt=build(,n,);
For(i,,n) {
T=q[i];
qry(rt,,n,);
}
printf("%lld\n",ans);
//cerr<<clock()<<endl;
Formylove;
}
kd-tree
正解:
这个题其实是三道题中最简单的一道。先来看这个问题的一个简化版,假设所有的属性都是差值越大越友好的话:
那么,这个题目会变得简单很多,我们依次枚举在最有情况下,每一种属性值是编号小的动物大,还是编号大的动物大。假设,对于第i种属性,编号小的动物大这种情况用t[i]=-1表示,编号大的动物属性值大这种情况用t[i]=1表示。那么,动物i和动物j的属性值
并且,我们总有一个时刻可以枚举对每一种属性的情况,使等号成立。所以,我们可以通过寻找右侧式子的最大值来确定左侧式子的最大值。
回到本题,题目中的最后一个属性和前面的是反过来的,即差值越小越友好,在这种情况下,我们可以先将动物们按照最后一个属性值来排序,之后按照上面给出的做法实现就可以了。
正解当然优美很多了
//Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
#define inf 1e18
const int N=;
using namespace std;
typedef long long LL;
typedef double db;
int n,K,D;
LL C[],ans; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int d[];
friend bool operator <(const node&A,const node&B) {
return A.d[K-]>B.d[K-];
}
}p[N]; #define ANS
int main() {
#ifdef ANS
freopen("species.in","r",stdin);
freopen("species.out","w",stdout);
#endif
read(n); read(K);
For(i,,K-) read(C[i]);
For(i,,n) {
For(j,,K-) read(p[i].d[j]);
}
sort(p+,p+n+);
LL pr=inf;
ans=-inf;
int up=(<<K-)-;
For(t,,up) {
pr=inf;
For(i,,n) {
LL tp=;
For(d,,K-) if(t&(<<d-)) tp-=C[d-]*p[i].d[d-];
else tp+=C[d-]*p[i].d[d-];
ans=max(ans,tp+C[K-]*p[i].d[K-]-pr);
pr=min(pr,tp+C[K-]*p[i].d[K-]);
}
}
printf("%lld\n",ans);
//cerr<<clock()<<endl;
Formylove;
}
基因重组
这是个真水题,n^2dp随便怎么做,我做的时候脑子有点抽写得有点奇怪,还用了short卡空间。。但是这个dp随便怎么写都能过吧。
//Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=;
using namespace std;
typedef long long LL;
typedef double db;
int n,m,up=,c1,c2,c3;
short s1[N][N],f[N][N],mi[N],ans;
LL x;
char a[N],b[N],a2[N]; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void get_min(short &x,int y) { if(x>y) x=y; } #define ANS
int main() {
#ifdef ANS
freopen("DNA.in","r",stdin);
freopen("DNA.out","w",stdout);
#endif
read(x); if(x>up) c1=up+; else c1=x;
read(x); if(x>up) c2=up+; else c2=x;
read(x); if(x>up) c3=up+; else c3=x;
scanf("%s",a); n=strlen(a);
For(i,,n-) {
if(a[i]=='A') a2[i]='T';
else if(a[i]=='T') a2[i]='A';
else if(a[i]=='C') a2[i]='G';
else if(a[i]=='G') a2[i]='C';
}
scanf("%s",b); m=strlen(b);
Rep(i,n,) Rep(j,m,) {
if(a[i-]==b[j-]) s1[i][j]=s1[i+][j+]+;
else s1[i][j]=;
if(a2[i-]==b[j-]) f[i][j]=f[i+][j+]+;
else f[i][j]=;
}
For(i,,n) For(j,,m) s1[i][j]=max(s1[i][j],f[i][j]);
memset(f,,sizeof(f));
memset(mi,,sizeof(mi));
mi[]=;
f[][]=; ans=up;
For(i,,n) {
For(j,,m) {
get_min(f[i][j],(int)mi[j]+c2);
mi[j]=min(mi[j],f[i][j]);
int t=s1[i+][j+];
get_min(f[i+t][j+t],(int)f[i][j]+c1);
if(j==m) get_min(ans,(int)f[i][j]);
else get_min(f[i][j+],(int)f[i][j]+c3);
}
}
printf("%d\n",(int)ans);
//cerr<<clock()<<endl;
Formylove;
}
危险的迷宫
好多人切这题啊。。。全机房就我一个人不知道这题是费用流???
这不是一道插头dp的裸题吗????
人类,你们对插头dp一无所知!
作死写了百行转移,结果大样例都没过,交上去还水过了50pt.
然后de了一晚上。。。
一个是有个地方n和m写反了,另外两个是两段轮廓线上一个是1一个是2的时候,如果这个格子本身是1或者2那么是不合法的,不能直接合并清0了!两句话价值一晚上+50pt。
//Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=;
using namespace std;
typedef long long LL;
typedef double db;
int n,m,K,C,f[][][N],inf,pr[];
int a[][],is[][],rr[][],dn[][]; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void GM(int &x,int y) { if(x>y) x=y; }
int get(int s,int k) {
return s/pr[k-]%;
} #define ANS
int main() {
#ifdef ANS
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
#endif
read(n); read(m);
For(i,,n) For(j,,m) read(a[i][j]);
read(K);
For(i,,K) {
int x1,y1,x2,y2;
read(x1); read(y1);
read(x2); read(y2);
if(x1>x2) swap(x1,x2),swap(y1,y2);
if(x1<x2) dn[x1][y1]=;
else {
if(y1>y2) swap(y1,y2);
rr[x1][y1]=;
}
}
read(C);
For(i,,C) {
int x,y;
read(x); read(y);
is[x][y]=;
}
For(i,,C) {
int x,y;
read(x); read(y);
is[x][y]=;
}
/*For(i,1,n) {
For(j,1,m) {
printf("%d ",rr[i][j]);
} puts("");
}
For(i,1,n) {
For(j,1,m) {
printf("%d ",dn[i][j]);
} puts("");
}
For(i,1,n) {
For(j,1,m) {
if(is[i][j]) printf("%d(%d)",a[i][j],is[i][j]);
else printf("%d",a[i][j]);
}*/
pr[]=;
For(i,,) pr[i]=pr[i-]*;
memset(f,/,sizeof(f));
inf=f[][][];
f[][][]=;
int up=pr[m+]-;
For(i,,n) {
For(j,,m) {
For(s,,up) if(f[i][j][s]!=inf) {
int prs=s;
if(j==) s*=;
int f1=get(s,j),f2=get(s,j+);
int ii,jj;
if(j==m) ii=i+,jj=;
else ii=i,jj=j+;
if(!f1) {
if(!f2) {
if(is[i][j]) {
if(rr[i][j]) GM(f[ii][jj][s+is[i][j]*pr[j]],f[i][j][prs]+a[i][j]);
if(dn[i][j]) GM(f[ii][jj][s+is[i][j]*pr[j-]],f[i][j][prs]+a[i][j]);
}
else {
GM(f[ii][jj][s],f[i][j][prs]);
if(rr[i][j]&&dn[i][j]) {
GM(f[ii][jj][s+pr[j-]+*pr[j]],f[i][j][prs]+a[i][j]);
GM(f[ii][jj][s+*pr[j-]+pr[j]],f[i][j][prs]+a[i][j]);
}
}
}
if(f2==) {
if(is[i][j]==)
GM(f[ii][jj][s-pr[j]],f[i][j][prs]+a[i][j]);
else if(!is[i][j]) {
if(rr[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
if(dn[i][j]) GM(f[ii][jj][s+pr[j-]-pr[j]],f[i][j][prs]+a[i][j]);
}
}
if(f2==) {
if(is[i][j]==)
GM(f[ii][jj][s-*pr[j]],f[i][j][prs]+a[i][j]);
else if(!is[i][j]) {
if(rr[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
if(dn[i][j]) GM(f[ii][jj][s+*pr[j-]-*pr[j]],f[i][j][prs]+a[i][j]);
}
}
}
else if(f1==) {
if(!f2) {
if(is[i][j]==)
GM(f[ii][jj][s-pr[j-]],f[i][j][prs]+a[i][j]);
else if(!is[i][j]) {
if(rr[i][j]) GM(f[ii][jj][s-pr[j-]+pr[j]],f[i][j][prs]+a[i][j]);
if(dn[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
}
}
if(f2==) ;
if(f2==&&!is[i][j])
GM(f[ii][jj][s-pr[j-]-*pr[j]],f[i][j][prs]+a[i][j]);
}
else if(f1==) {
if(!f2) {
if(is[i][j]==)
GM(f[ii][jj][s-*pr[j-]],f[i][j][s]+a[i][j]);
else if(!is[i][j]) {
if(rr[i][j]) GM(f[ii][jj][s-*pr[j-]+*pr[j]],f[i][j][s]+a[i][j]);
if(dn[i][j]) GM(f[ii][jj][s],f[i][j][s]+a[i][j]);
}
}
if(f2==&&!is[i][j])
GM(f[ii][jj][s-*pr[j-]-pr[j]],f[i][j][s]+a[i][j]);
if(f2==) ;
}
s=prs;
if(f[][][]!=inf) {
int debug=;
}
}
}
}
if(f[n+][][]==inf) puts("-1");
else printf("%d\n",f[n+][][]);
//cerr<<clock()<<endl;
Formylove;
}
NOIp2018集训test-9-23的更多相关文章
- NOIP2018 集训(二)
A题 神炎皇 问题描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对 \((a,b)\) ,若满足 \(a+b\leq n\) 且 \(a+b\) 是 \(ab\) 的因子,则称 为神 ...
- NOIP2018 集训(一)
A题 Simple 时间限制:1000ms | 空间限制:256MB 问题描述 对于给定正整数\(n,m\),我们称正整数\(c\)为好的,当且仅当存在非负整数\(x,y\)使得\(n×x+m×y=c ...
- 【纪中集训2019.3.23】Deadline
题意 描述 一个二分图\((A,B)\),每个点额外有一个颜色0或者1: 匹配时,只能相同颜色的点匹配: 给出\(A\)中的颜色,问如何分配\(B\)种的颜色使得\((A,B)\)的最大匹配最小: 范 ...
- 【纪中集训2019.3.23】IOer
题目 描述 你要在\(m\)天内,刷\(n\)道题,每天可以刷的题的数目不限: 第\(i\)天可以刷的题目的种类是\(ui+v\): 两种刷题的方案不同当且仅当某天刷题的数量不同或者依次刷题的种类不同 ...
- NOIp2018集训test-10-24(am&pm)
李巨连续AK三场了,我跟南瓜打赌李巨连续AK七场,南瓜赌李巨连续AK五场. DAY1 T1 qu 按题意拿stack,queue和priority_que模拟即可.特判没有元素却要取出的情况. T2 ...
- NOIP2018 集训(三)
A题 Tree 问题描述 给定一颗 \(n\) 个点的树,树边带权,试求一个排列 \(P\) ,使下式的值最大 \[\sum_{i=1}^{n-1} maxflow(P_i, P_{i+1}) \] ...
- NOIp2018集训test-10-18 (bike day4)
这是一套简单题,这几天的考试让bike老爷感觉很绝望,说实话我也确实不知道还能怎么更简单了. 这几天的题换做llj.sxy应该都能轻松AK吧,至少随便考个250+应该不是问题吧,我越来越觉得觉得我跟他 ...
- NOIp2018集训test-10-17 (bike day3)
发现自己gradully get moodier and moodier了 负面情绪爆发地越来越频繁,根本out of control,莫名其妙地就像着了魔一样 为什么用英语大概是因为今天早上早自习因 ...
- NOIp2018集训test-10-16 (bike day2)
“毕姥爷:今天的题好简单啊,你们怎么考得这么烂啊,如果是noip你们就凉透了啊“ 今天的题难度应该是3.2.1递减的,但是我不知道哪根筋没搭对,平时我最多1h多就弃题了,今天硬生生写了2h20min的 ...
- [雅礼NOIP2018集训] day6
打满暴力好像是一种挑战,已经连续几天考试最后一个小时自闭了,因为自以为打完了暴力,然而,结果往往差强人意 大概是考试的策略有些问题 T1: 我们设$g[x]$为在x时取小于等于m个物品的最大价值,下面 ...
随机推荐
- AngularJS 项目开发实战
目录 啰嗦一下 你问我答 目录结构 压缩 其他 啰嗦一下 最近在开发一个项目时,调研了一下AngularJS,发现这个框架功能很丰富,而且用起来也很方便,所以深入了解了一下,在此分享一下我的感悟. A ...
- git命令的基本使用
git init 创建仓库 git status 查看当前版本库的状态 git add filename 使用git add命令告诉git,把该文件添加到仓库 git commit -m 'c ...
- bcpow — 任意精度数字的乘方
bcpow — 任意精度数字的乘方 说明 string bcpow ( string $left_operand , string $right_operand [, int $scale ] ) 左 ...
- IT类影视
1.爱奇艺 代码(The Code) 2.爱奇艺 操作系统革命(Revolution OS) 3.爱奇艺 互联网之子 4.爱奇艺 深网
- 【leetcode】962. Maximum Width Ramp
题目如下: Given an array A of integers, a ramp is a tuple (i, j) for which i < j and A[i] <= A[j]. ...
- HIVE(2) 之 常用函数
LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值 第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为N ...
- Java分支结构
Java 分支结构 - if...else/switch 顺序结构只能顺序执行,不能进行判断和选择,因此需要分支结构. Java有两种分支结构: if语句 switch语句 if语句 一个if语句包含 ...
- 关于C语言命令行参数问题
1 int main(int argc,char** argv) 参数: argc:命令行参数的个数 argv:保存命令行参数:argv[0]保存本程序自己的名称 现在自己只知道这些以后再有学习继续补 ...
- Jeecg 3.8修改lhgDialog弹窗的样式
位置:F:\jeecg-bpm-3.8\eecg-bpm-3.8-master\jeecg-bpm-3.8\src\main\java\org\jeecgframework\core\util pub ...
- Java目录事件
当文件系统中的对象被修改时,我们可以监听watch服务以获取警报.java.nio.file包中的以下类和接口提供watch服务. Watchable接口 WatchService接口 WatchKe ...