zoukankan      html  css  js  c++  java
  • SDOJ 1195 Zhenhuan

    描述

    今日又在看甄嬛传,皇上觉得后宫们的勾心斗角太险恶了,有点不好,决定给每个妃子发丝带以让后宫之间和睦相处。皇上一共有N个后宫(标号为1~n),站成一个环形(1号与n号相邻),每个后宫想要ai个丝带,而且这ai个丝带颜色互不相同,而且每个妃子拥有的丝带不能与和她相邻的妃子的丝带有任何一种颜色相同。

    皇上不喜欢太多的颜色,所以皇上就像知道最少需要多少种颜色就能满足所有后宫的要求,设最小颜色为M,而甄嬛想提前知道M的值,以告诉皇上来赢得欢心,然而在皇上后宫太多了,她就不会了,所以呢,她向学信息奥赛的你求助,并答应事成之后奖励你

    21,000,000,006mod1,000,000,0071(21,000,000,006mod1,000,000,007)−1吨黄金

    输入

    第一行一个整数n,接下来有n个数字,第i个数字为ai,表示编号为i的后宫想要ai条丝带。

    输出

    一个整数表示M

    样例输入

    13
    960
    2
    465
    159
    628
    110
    88
    592
    193
    546
    880
    400
    622

    样例输出

    1582

    数据范围: 40%的数据:n mod 2==0。0<=ai<=1,000,000,000; 100%的数据:n<=20000。0<=ai<=1,000,000,000;

     

    ----------------------------------------------------这是一条分界线-------------------------------------------------------

     

    这道题首先想到的是贪心,分类讨论n%2=1和n%2=0的情况(但听说最高调到了90分????)

    而实际上这是个二分答案。二分ans,并判定其是否满足

    而说到判定,我觉得这个过程又有点像DP.....

    【以下受某blog启发】

          判定答案ans,即1与n的最小冲突个数是否为0令mi[i]表示1与i的最小冲突个数,ma[i]表示1与i的最大冲突个数。

          那么有: 

          1.最多能冲突那么就是全部都冲突了或是分了上一个冲突了的。 

          ma[i]=minai,a1mi[i1] }

          

          2.最小能冲突那么就是一个都不冲突,否则需要知道最多不冲突的个数,由上一个最多冲突的个数求得。 

          mi[i]=max{ 0,ai-[ans-ai-1-(a1-ma[i-1])] }

          那么mi[n]==0就表示当前答案可行 

                    ”

     于是贴代码~

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int n,ans;
     8 int ma[20010],mi[20010];
     9 int a[20010];
    10 bool check(int x)
    11 {
    12     ma[1]=mi[1]=a[1];
    13     for(int i=2;i<=n;i++)
    14     {
    15         ma[i]=min(a[i],a[1]-mi[i-1]);
    16         mi[i]= max( 0, a[i] - ( x-a[i-1]-(a[1]-ma[i-1]) ) );
    17     }
    18     return mi[n];
    19 }
    20 int main()
    21 {
    22     scanf("%d",&n);
    23     for(int i=1;i<=n;i++)
    24         scanf("%d",&a[i]);
    25     for(int i=2;i<=n;i++)
    26         ans=max(ans,a[i]+a[i-1]);
    27     int l=ans,r=ans*2,mid;
    28     while(l<=r)
    29     {
    30         mid=(l+r)>>1;
    31         if (check(mid)) l=mid+1;
    32         else r=mid-1;
    33     }
    34     printf("%d",l);
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    原生searchView 自定义样式
    面试问题总结
    Android Studio开发环境搭建
    JAVA基本程序设计结构
    JAVA大数使用
    sql
    普通树的递归遍历
    6_43_递归交换二叉树中所有节点的左右子树
    6_42_二叉树递归求叶子节点个数
    6_44_二叉树中值为x的节点为根的子树的深度
  • 原文地址:https://www.cnblogs.com/kylara/p/9440042.html
Copyright © 2011-2022 走看看