期望得分:100+30+60=190

实际得分:100+30+30=160

T1

最优方案跳的高度一定是单调的

所以先按高度排序

dp[i][j] 跳了i次跳到j

枚举从哪儿跳到j转移即可

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; #define N 51 struct node
{
int c,h;
}e[N]; int dp[N][N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} bool cmp(node p,node q)
{
return p.h<q.h;
} int main()
{
freopen("meet.in","r",stdin);
freopen("meet.out","w",stdout);
int n;
read(n);
for(int i=;i<=n;i++) read(e[i].c);
for(int i=;i<=n;i++) read(e[i].h);
sort(e+,e+n+,cmp);
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++) dp[][i]=e[i].c;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
for(int k=;k<j;k++)
dp[i][j]=min(dp[i][j],dp[i-][k]+e[j].h-e[k].h);
dp[i][j]+=e[j].c;
}
int t;
read(t);
for(int i=n;i>=;i--)
for(int j=;j<=n;j++)
if(dp[i][j]<=t) { printf("%d",i+); return ; }
}

T2

设给出的数是b1,b2,……

解为a1,a2……

那么可以得到 b1=a1+a2,b2=a1+a3

如果再知道 a2+a3=X,就可以解出a1,a2,a3

在b中把b1 b2 X 删去

剩下的最小的一定是 a1+a4,解出a4

再把a2+a4 ,a2+a4 删去,剩下的最小的一定是a1+a5

以此类推,解出所有的a

即

每确定一个ai
就把 aj+ai  j∈[1,i) 全删去
剩下的最小的一定是a1 和ai+1 的和

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; int n,m,tot; #define N 302 int b[N*N]; int ans[N*N][N],t[N]; bool use[N*N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void work(int x)
{
if((b[]+b[]+b[x])&) return;
t[]=b[]-b[]+b[x]>>;
t[]=b[]-t[];
t[]=b[]-t[];
memset(use,false,sizeof(use));
use[]=use[]=use[x]=true;
int r,pos;
for(int i=,k=;i<=m;++i)
{
if(use[i]) continue;
t[k]=b[i]-t[];
for(int j=;j<k;++j)
{
r=t[j]+t[k];
pos=lower_bound(b+,b+m+,r)-b;
if(b[pos]!=r) return;
while(pos<m && use[pos] && b[pos]==r) pos++;
if(b[pos]!=r) return;
use[pos]=true;
}
k++;
}
tot++;
for(int i=;i<=n;i++) ans[tot][i]=t[i];
} int main()
{
freopen("city.in","r",stdin);
freopen("city.out","w",stdout);
read(n);
m=n*(n-)/;
for(int i=;i<=m;++i) read(b[i]);
sort(b+,b+m+);
for(int i=;i<=m;++i)
{
if(i> && b[i]==b[i-]) continue;
work(i);
}
printf("%d\n",tot);
for(int i=;i<=tot;++i)
{
for(int j=;j<=n;++j) printf("%d ",ans[i][j]);
printf("\n");
}
}

T3

分块

因为街灯上的数不超过1e4,所以p最多有1e4个

用vector[i][j] 存下%i=j 的数的位置 i<=100

当p<=100 时,直接在vector[p][v] 里二分在区间[l,r]内的最左位置和最右位置

再用一个vector[i] 存下所有的街灯数位i的位置

当p>100 时,%p=v 的数 有v,v+p,v+2p……

直接枚举这些数,最多100个,在vector[i] 里 二分 在区间[l,r]内的最左位置和最右位置

#include<cstdio>
#include<vector>
#include<iostream> using namespace std; #define N 100001 int a[N]; vector<int>V1[][];
vector<int>V2[]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int main()
{
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
int n,m;
read(n); read(m);
for(int i=;i<=n;++i) read(a[i]),V2[a[i]].push_back(i);
for(int i=;i<=;++i)
for(int j=;j<=n;++j)
V1[i][a[j]%i].push_back(j);
int l,r,p,v;
int L,R,MID,TMP1,TMP2;
int pos,tot;
while(m--)
{
read(l); read(r); read(p); read(v);
if(p<=)
{
L=; R=V1[p][v].size()-;
TMP1=TMP2=-;
while(L<=R)
{
MID=L+R>>;
if(V1[p][v][MID]>=l) TMP1=MID,R=MID-;
else L=MID+;
}
if(TMP1==-) { puts(""); continue; }
L=TMP1; R=V1[p][v].size()-;
while(L<=R)
{
MID=L+R>>;
if(V1[p][v][MID]<=r) TMP2=MID,L=MID+;
else R=MID-;
}
if(TMP2==-) { puts(""); continue; }
printf("%d\n",TMP2-TMP1+);
}
else
{
pos=v; tot=;
while(pos<=)
{
L=; R=V2[pos].size()-;
TMP1=TMP2=-;
while(L<=R)
{
MID=L+R>>;
if(V2[pos][MID]>=l) TMP1=MID,R=MID-;
else L=MID+;
}
if(TMP1==-) { pos+=p; continue; }
L=TMP1; R=V2[pos].size()-;
while(L<=R)
{
MID=L+R>>;
if(V2[pos][MID]<=r) TMP2=MID,L=MID+;
else R=MID-;
}
if(TMP2==-) { pos+=p; continue; }
tot+=TMP2-TMP1+;
pos+=p;
}
printf("%d\n",tot);
}
}
}

60分暴力

#include<vector>
#include<cstdio>
#include<iostream> using namespace std; #define N 100001 int n,m,a[N]; int P; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} namespace solve1
{
int l,r,p,v,ans;
void work()
{
while(m--)
{
read(l); read(r); read(p); read(v);
ans=;
for(int i=l;i<=r;i++)
if(a[i]%p==v) ans++;
printf("%d\n",ans);
} }
} namespace solve2
{
vector<int>V[];
void work()
{
int l,r,p,v;
int L,R,MID,TMP1,TMP2;
for(int o=;o<=m;o++)
{
read(l); read(r); read(p); read(v);
if(o==)
{
P=p;
for(int i=;i<=n;i++) V[a[i]%P].push_back(i);
}
if(v> || !V[v].size()) { puts(""); continue; }
L=,R=V[v].size()-; TMP1=-;
while(L<=R)
{
MID=L+R>>;
if(V[v][MID]>=l) TMP1=MID,R=MID-;
else L=MID+;
}
if(TMP1==- || V[v][TMP1]>r) { puts(""); continue; }
L=TMP1,R=V[v].size()-; TMP2=-;
while(L<=R)
{
MID=L+R>>;
if(V[v][MID]<=r) TMP2=MID,L=MID+;
else R=MID-;
}
if(TMP2==-) { puts(""); continue; }
printf("%d\n",TMP2-TMP1+);
}
}
} void init()
{
read(n); read(m);
for(int i=;i<=n;i++) read(a[i]);
if(1ll*n*m<=1e6) solve1::work();
else solve2::work();
} int main()
{
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
init();
}

2017 清北济南考前刷题Day 2 morning的更多相关文章

  1. 2017 清北济南考前刷题Day 7 afternoon

    期望得分:100+100+30=230 实际得分:100+100+30=230 1. 三向城 题目描述 三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口.(来自取名力为0的 ...

  2. 2017 清北济南考前刷题Day 1 afternoon

    期望得分:80+30+70=180 实际得分:10+30+70=110 T1 水题(water) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK出了道水 ...

  3. 2017 清北济南考前刷题Day 3 morning

    实际得分:100+0+0=100 T1 右上角是必败态,然后推下去 发现同行全是必胜态或全是必败态,不同行必胜必败交叉 列同行 所以n,m 只要有一个是偶数,先手必胜 #include<cstd ...

  4. 2017 清北济南考前刷题Day 3 afternoon

    期望得分:100+40+100=240 实际得分:100+40+100=240 将每个联通块的贡献乘起来就是答案 如果一个联通块的边数>点数 ,那么无解 如果边数=点数,那么贡献是 2 如果边数 ...

  5. 2017 清北济南考前刷题Day 4 afternoon

    期望得分:30+50+30=110 实际得分:40+0+0=40 并查集合并再次写炸... 模拟更相减损术的过程 更相减损术,差一定比被减数小,当被减数=减数时,停止 对于同一个减数来说,会被减 第1 ...

  6. 2017 清北济南考前刷题Day 7 morning

    期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...

  7. 2017 清北济南考前刷题Day 6 afternoon

    期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...

  8. 2017 清北济南考前刷题Day 6 morning

    T1 贪心 10 元先找5元 20元 先找10+5,再找3张5 #include<cstdio> using namespace std; int m5,m10,m20; int main ...

  9. 2017 清北济南考前刷题Day 5 afternoon

    期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...

  10. 2017 清北济南考前刷题Day 5 morning

    期望得分:100+100+0=200 实际得分: 坐标的每一位不是0就是1,所以答案就是 C(n,k) #include<cstdio> #include<iostream> ...

随机推荐

  1. 【图论】POJ-3169 差分约束系统

    一.题目 Description Like everyone else, cows like to stand close to their friends when queuing for feed ...

  2. Internet 校验和的数学性质

    Internet 校验和(Checksum)仅计算头部的正确性,这一点很重要,这意味着 IP 协议不检查 IPv4 packet 有效载荷部分的数据正确性.为了保证有效载荷部分的正常传输,其他协议必须 ...

  3. 程序开发入门工具之CodeBlocks

    程序开发基础工具之CodeBlocks 作为程序开发工作者,我们会接触很多的程序开发软件:但实用以及容易掌握的程序开发软件对于初学者的学习能力是有一定的加成的.今天我就作为一个程序开发者给大家推荐一个 ...

  4. 转 彻底理解js中的&&和||

    javascript中,&&和||的用法比较神奇,经常用在对象上,例如a || b,如果a不存在,则返回b.a && b,如果a存在,则返回b,否则返回a. 光这样看, ...

  5. Beta阶段冲刺前的准备

    Beta阶段冲刺前的准备 凡事预则立,在Beta开始前,以小组为单位,在敏捷冲刺前发布一篇博客,描述: 1. 讨论组长是否重选的议题和结论 经过我们小组在周二下午的会议中有重新认真的考虑了是否要更换组 ...

  6. windows 下查看进程开始运行的时间

    1. 打开运行 输入 msinfo32 然后在软件环境- 正在运行任务- 就能够看到运行开始的时间了.

  7. Fastqc使用说明

    用FastQC检查二代测序原始数据的质量 2013-01-28 21:28:10|  分类: Bioinformatics |  标签:bioinformatics  deep-seq   |举报 | ...

  8. [Linux] 关于 history 命令的简单使用

    1. 如果不想记录当前 会话操作的命令的话 可以使用命令 set +o history 但是这个命令有一个坏处, 他自己被记住了... 2. 还有一个办法 就是 在退出登录之前执行命令 history ...

  9. 斑马条码打印机GK888T打印标签是间隔的 ,不是连续的

    有间断的标签纸和连续的标签纸是两种不同的纸张类型, 打印机的标签感应器需要工作在不同的模式来跟踪感应它们. 打印机正确感应纸张才不会红灯闪烁,打印的内容才按文件设计打印到标签的对应位置上. 所以要在驱 ...

  10. VIM 命令收藏

    1.vim#在命令行中输入vim,进入vim编辑器2.i#按一下i键,下端显示 --INSERT--#插入命令,在vim中可能任意字符都有作用3.Esc#退出i(插入)命令进行其它命令使用4.:r f ...