大家好,欢迎来到IT知识分享网。
NOIP2011 提高组 复赛 day1 hotel 选择客栈
1.结构体是少不了了,本题若用n^2,估计要超时,只能得50分。
2.按常规的做法,傻傻的找,肯定涉及n^2。
3.第一步,对合适的咖啡馆进行标记,
4.思路集中于扫描一遍,将答案算出。
5.受到最长上升子序列(动态规划中典型问题)启发,对i处,包括i之前每种颜色个数进行记录,开个二维数组。
6.合适的咖啡馆,可以放在结尾酒店,中间酒店,开始酒店三个位置,三个位置统计完毕后,该合适咖啡馆任务完成。
7.该合适咖啡馆下一个位置开始如上6情况进行雷同处理。
8.其实题目条件也有提示,2 ≤n ≤200,000,0<k ≤50,n*K<=10^7,开个二维数组,正合适。
9.思路清晰后,开始编码,估计能得100分。
10.按照思路,编码过程中,感觉很想用递归,但不熟练,还是先用非递归。
11.处理过程中,有无越界,+1还是-1感觉有点烦,耐着性子还是编好。
12.不放心啊,自个造了一组测试数据:
输入:
5 2 3
1 2
1 3
1 2
1 3
1 3
输出:
10
经程序验证,成功。
13.怀着忐忑的心情,提交,AC。
一次成功。完全凭自身,没有参考任何东西,很是高兴,这个算法是磨出来的,跟积累是分不开的。
14.没完,想一想,用递归能不能实现。
15.网上搜了很多好解法,可惜功力不够,看不懂啊,暂且搁置,水平高了,再回头来看。
难度:中等偏难
好时:60分钟,(思考的时间有点长,先是一头雾水,后面才慢慢进入状态)
附上AC代码,编译环境Dev-C++4.9.9.2
//2011 hotel 很想用递归,但不熟练,还是先用非递归
#include <stdio.h>
#include <string.h>
struct node{
int color;
int pay;
}h[200000+10];//旅馆信息
int ka[200000+10];//符合提交咖啡馆
int hc[200000+10][50+10];//统计i位置之前包括i位置颜色种类统计
int main(){
int n,k,p;
int i,j,c;
int kacount=0;
int sum=0;
int before_pos,now_pos;
memset(h,0,sizeof(h));
memset(ka,0,sizeof(ka));
memset(hc,0,sizeof(hc));
scanf(“%d%d%d”,&n,&k,&p);
for(i=1;i<=n;i++)
scanf(“%d%d”,&h[i].color,&h[i].pay);
for(i=1;i<=n;i++){//标记信息
if(h[i].pay<=p){
kacount++;
ka[kacount]=i;//统计符合条件的咖啡馆位置,从1开始
}
hc[i][h[i].color]++;//统计i处的颜色情况。
}
for(i=2;i<=n;i++){
for(j=0;j<k;j++){
hc[i][j]+=hc[i-1][j];//统计i处包括i之前颜色情况
}
}
ka[0]=0;//为了照顾数据处理,该处人为定义
for(i=1;i<=kacount;i++){//对每个符合条件的咖啡馆做后,中,前位置处理。
before_pos=ka[i-1];//之前符合条件,咖位啡馆置
now_pos=ka[i];//当前符合条件,咖位啡馆置
//该咖啡馆在最后
if(now_pos-1>before_pos)
sum+=(hc[now_pos-1][h[now_pos].color]-hc[before_pos][h[now_pos].color]);
//该咖啡馆在中间
if(now_pos-1>before_pos&&now_pos+1<=n){
for(c=0;c<k;c++){
sum+=(hc[now_pos-1][c]-hc[before_pos][c])*(hc[n][c]-hc[now_pos][c]);
}
}
//该咖啡馆在最前
if(now_pos+1<=n)
sum+=(hc[n][h[now_pos].color]-hc[now_pos][h[now_pos].color]);
}
printf(“%d\n”,sum);
return 0;
}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/25865.html