Description

圆桌上摆放着n份食物,围成一圈,第i份食物所含热量为c[i]。

相邻两份食物之间坐着一个人,共有n个人。每个人有两种选择,吃自己左边或者右边的食物。如果两个人选择了同一份食物,这两个人会平分这份食物,每人获得一半的热量。

假如某个人改变自己的选择后(其他n-1个人的选择不变),可以使自己获得比原先更多的热量,那么这个人会不满意。

请你给每个人指定应该吃哪一份食物,使得所有人都能够满意。

Input

第一行一个整数n(2<=n<=1000000),表示食物的数量(即人数)。食物和人都从1~n编号。

第二行包含n个整数c[1],c[2],…,c[n](1<=c[i]<=10^9)。

假设第i个人(1<=i<n)左边是第i份食物,右边是第i+1份食物;而第n个人左边是第n份食物,右边是第1份食物。

Output

如果不存在这样的方案,仅输出一行NIE。

如果存在这样的方案,输出一行共n个整数,第i个整数表示第i个人选择的食物的编号。如果有多组这样的方案,输出任意一个即可。

Sample Input

5
5 3 7 2 9

Sample Output

2 3 3 5 1

思路:敲到吐血的题,其实这货就是微观经济学中的帕累托有效率嘛

这题第一眼看:傻逼题,枚举第一个人吃左边还是右边的食物,那第二个人选择左边还是右边就是固定的了,还想到了个貌似靠谱的优化:如果左边(或者右边)的数大于右边(或者左边)的数的两倍,那毋庸置疑是吃左边(右边)的。

然后我就WA了一下午。。。后来才发现思路错了

转换思路后,考虑O(n)的算法,dp[i][s]表示第i份食物吃的状态,1表示这份食物被左边的人吃,2表示这份食物被右边的人吃,3表示被两边的人吃,4表示两边的人都不吃这份食物,然后就可以转移了。什么?dp想出状态转移就很快出来了?唔 你可以试下这题。。。关键不在于转移很难想,而是细节很麻烦,注意什么时候乘二,符号是大于还是等于,之类的细节,最好在纸上画一下

顺便给两组数据:

10

8 7 3 10 5 2 1 3 8 4

ans:

1 2 4 4 5 6 8 9 9 10

3

10 1 10

ans:

1 3 3

//dp[i][1] left dp[i][2] right

//dp[i][3] both dp[i][4] none

#include<cstdio>

#include<string.h>

#define maxn 1000005

using namespace std;

int n,a[maxn],path[maxn][5],ans[maxn];

int work(int u){

memset(path,0,sizeof(path));path[1][u]=1;

for(int i=2;i<=n;i++){

if(path[i-1][1]&&(a[i-1]<=2*a[i]))path[i][1]=1;

if(path[i-1][4]&&(a[i-1]<=a[i]))path[i][1]=4;

if(path[i-1][2]&&(a[i-1]*2>=a[i]))path[i][2]=2;

if(path[i-1][3]&&(a[i-1]>=a[i]))path[i][2]=3;

if(path[i-1][1]&&(a[i-1]<=a[i]))path[i][3]=1;

if(path[i-1][4]&&(a[i-1]*2<=a[i]))path[i][3]=4;

if(path[i-1][2]&&(a[i-1]>=a[i]))path[i][4]=2;

if(path[i-1][3]&&(a[i-1]>=a[i]*2))path[i][4]=3;

}if(path[n][u]==0)return 0;

for(int i=n;i>=1;i--){

if(u==1)ans[i-1]=(i-1)%(n-1)+1;if(u==2)ans[i]=(i-1)%(n-1)+1;

if(u==3)ans[i-1]=ans[i]=(i-1)%(n-1)+1;

u=path[i][u];

}

for(int i=1;i<n-1;i++)printf("%d ",ans[i]);

printf("%d\n",ans[n-1]);

return 1;

}

int main(){

scanf("%d",&n);

for(int i=1;i<=n;i++)scanf("%d",&a[i]);a[++n]=a[1];

for(int i=1;i<=4;i++)if(work(i))return 0;

printf("NIE\n");

return 0;

}

最新文章

  1. mybatis批量删除提示类型错误
  2. ThinkPHP5 助手函数
  3. linux驱动开发之块设备学习笔记
  4. Atitit.gui api自动化调用技术原理与实践
  5. Eclipse自动补全功能管理
  6. SharedPreferences
  7. HDFS的运行原理(转)
  8. 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
  9. JAVA学习笔记--二
  10. Single Number,Single Number II
  11. 简单的刷票系统(突破IP限制进行投票) (转)
  12. python 多进程间交换信息与共享信息
  13. Java基础面试知识点总结
  14. 总结-shell脚本
  15. 8.3 GOF设计模式二: 适配器模式 Adapter
  16. python data science handbook1
  17. 记一个centos分区大小调整过程
  18. FineUIMvc随笔(2)怎样在控件中嵌套 HTML
  19. 转载:浅谈 Scala 中下划线的用途
  20. c# 十进制转二、八、十六进制

热门文章

  1. [翻译] API测试的最佳实践 - 介绍
  2. UIButton Making the hit area larger
  3. ImportError: No module named flask.ext.wtf 解决方法
  4. iOS的设计备忘录/资源集合(新手快速开发)
  5. mac上使用命令行显示隐藏文件
  6. |chromosomal walk |zoo blot|鉴定疾病gene|
  7. xheditor的实例程序—类似word的编辑器
  8. 函数的参数是函数,函数中Ajax返回的回调函数中的函数运行
  9. iOS开源库
  10. ST3使用