Vijos 3764 牛奶题
来源:互联网 发布:cms监控软件操作说明 编辑:程序博客网 时间:2024/06/05 05:00
【问题描述】
这是一道魔改的奶牛题,所以被称为牛奶题。
wdz的牛奶厂里面有N桶排成一排的牛奶,每一桶牛奶都有一个品质值。我们为wdz定义如下的一种操作:选择两桶相邻的品质值相同(设为X)的牛奶,通过奥妙重重的步骤,合并为一桶品质值为X+1的牛奶并放在原来的位置(此时原来的两桶牛奶已经被取走)。
wdz想要通过若干次上述操作得到一桶品质值尽可能大的牛奶(即最大化 所有牛奶品质值中的最大值 ),但是wdz日理万机非常繁忙,所以他请你来帮忙求出这个最大值。
【输入格式】
输入的第1行一个非负整数n,意义见题目描述。第2到n+1行共n个正整数,第i个数表示第i桶牛奶的品质值,数组保证最初的品质值均为1到40之间的整数(也就是说在操作之后最大值超过40是被允许的)。
【输出格式】
输出一行一个整数表示答案。
【输入样例】
8
3
2
1
1
1
2
3
4
【输出样例】
5
【数据范围】
对于30%的数据,保证n<=2,000
这是一道魔改的奶牛题,所以被称为牛奶题。
wdz的牛奶厂里面有N桶排成一排的牛奶,每一桶牛奶都有一个品质值。我们为wdz定义如下的一种操作:选择两桶相邻的品质值相同(设为X)的牛奶,通过奥妙重重的步骤,合并为一桶品质值为X+1的牛奶并放在原来的位置(此时原来的两桶牛奶已经被取走)。
wdz想要通过若干次上述操作得到一桶品质值尽可能大的牛奶(即最大化 所有牛奶品质值中的最大值 ),但是wdz日理万机非常繁忙,所以他请你来帮忙求出这个最大值。
【输入格式】
输入的第1行一个非负整数n,意义见题目描述。第2到n+1行共n个正整数,第i个数表示第i桶牛奶的品质值,数组保证最初的品质值均为1到40之间的整数(也就是说在操作之后最大值超过40是被允许的)。
【输出格式】
输出一行一个整数表示答案。
【输入样例】
8
3
2
1
1
1
2
3
4
【输出样例】
5
【数据范围】
对于30%的数据,保证n<=2,000
对于100%的数据,保证n<=300,000,最初给出的品质值均为不超过40的正整数。
由于对品质值小的桶进行合并不会限制对品质值大的桶的合并,可以发现合并操作是无后效性的,自然而然地考虑贪心,由小到大合并,每次合并连续相等的一段桶,按长度为奇数/偶数分类讨论。
设合并前桶的品质值为X:
(1)如果连续项长度为偶数(假设有2*k桶),两两合并成k桶,每桶品质值为X+1即可。(每次合并品质值只+1,还能合并的情况之后再考虑)
(2)如果连续项长度为奇数(假设有2*k+1桶),则无论怎样合并,都会单独剩下一桶无法合并,又由于我们是按桶的品质由小到大合并的,则剩下的这一桶以后也不会再被合并了,所以以它作为分隔,其左右两边的桶被划分成两个互不影响的部分。现在的问题是我们合并出了k桶品质值为X+1的桶,我们应该将它们放在分隔桶的右边还是放在左边?事实证明我们事先是不知道该放在哪边的, 所以我们可以选择一种很巧妙的放置方式------我们在左右两边都各放置k桶品质值为X+1, 虽然实际上这是不可能的,但由于分隔桶的划分,这样做对最后的答案并没有影响。
上述操作可以用链表实现,最后遍历所有的桶找出品质值最大的那一桶即可。
另:牛奶桶可能的极大品质值为40+log2(300000),约为58。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn=300000+5;const int inf =1e8;int N;struct Chain{int from;int v;int to;}Bucket[maxn];void init(){scanf("%d",&N);for(int i=1;i<=N;i++){scanf("%d",&Bucket[i].v); Bucket[i].from=i-1;Bucket[i].to=i+1;}Bucket[N+1].from=N; //(1)return;}void solve(){ int i,k,e,mid,cnt,ans; for(i=1;i<=57;i++) { for(k=1;k<=N;k=Bucket[k].to) if(Bucket[k].v==i) { e=k,cnt=0; while(e<=N&&Bucket[e].v==i) {cnt++;e=Bucket[e].to; } e=Bucket[e].from; //如果不写(1)这一步,(2)这一步后e=0,将进入死循环。 if(cnt%2) { mid=k; for(int j=1;j<=(cnt-1)/2;j++) mid=Bucket[mid].to; for(int p=k;p!=mid;p=Bucket[p].to) Bucket[p].v++; for(int p=e;p!=mid;p=Bucket[p].from) Bucket[p].v++; } else { mid=k; for(int j=1;j<cnt/2;j++) mid=Bucket[mid].to; Bucket[mid].to=Bucket[e].to; Bucket[Bucket[e].to].from=mid; mid=Bucket[mid].to; for(int p=k;p!=mid;p=Bucket[p].to) Bucket[p].v++; } k=e; } } ans=0; for(k=1;k<=N;k++) ans=max(ans,Bucket[k].v); printf("%d\n",ans); return;}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);init();solve();return 0;}
阅读全文
0 0
- Vijos 3764 牛奶题
- ..牛奶..
- 牛奶
- Vijos 1034题:家族
- Vijos 1104题:采药
- Vijos 1166题:木牛流马
- Vijos 1193题:扫雷
- Vijos 1217题:乒乓球
- Vijos 1359题:Superprime
- Vijos 1549题:中位数
- Vijos 1773题:质因数
- Vijos 1002题:过河
- 第二层第一题:挤牛奶
- vijos P1753HackSon的趣味题
- Vijos 1304题:回文数
- Vijos 1036题:安装服务器
- Vijos 1133题:装箱问题
- Vijos 1172题:反质数
- ExtJs6学习(一)【ExtJs介绍】
- 使用mybatis分页插件PageHelper5.0.0遇到的问题总结
- Redis 启动多实例
- sql导出导入备份恢复
- js兼容性2
- Vijos 3764 牛奶题
- Android模拟器Genymotion安装apk
- 每日练习20171108
- 【云星数据---大数据部集群署系列004】:zookeeper分布式部署方案
- F2L
- php怎么样提前响应,后续代码在后台继续运行,但是阻塞模式
- 冒泡排序
- 浅谈http协议(面试重点)
- 在centos7系统中如何查看网卡IP