zoukankan      html  css  js  c++  java
  • uva1614 Hell on the Markets

    贪心部分的理论依据:前i个数可以凑出1~sum[i]的所有整数。

    证明:第二类数学归纳,n=1时成立,假设n=k之前所有项都成立,当n=k+1时。sum[k+1]=sum[k]+a[k+1]。
    只需证明能凑出sum[k]+1~sum[k+1]间的整数即可。设1≤p≤a[k+1],sum[k]+p=sum[k]+a[k+1]-(a[k+1]-p)。
    因为1≤a[i]≤i,易得sum[k]≥k,a[k+1]-p≤k。又因为已知前k个数可以凑出1~sum[k],所以一定可以凑出a[k+1]-p。
    所以只需从之前凑出sum[k]里面剪掉凑出a[k+1]-p的数就可以凑出sum[k]+p。所以从1~sum[k+1]都可以凑出。

    实现就是输入时存一下sum,若为奇数就无解,否则再排个序,从大到小扫一遍,选凑成和为sum/2的数的符号为+,其余为-。

    先排序,从大到小减(不然会多减小的)

    注意sum 用 ll

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int maxn=100005;
    
    struct node{
    int x,id;
    }
    a[maxn];
    int ans[maxn];
    bool cmp(node x,node y) {return x.x>y.x;}
    
    int main()
    {
        int n;
        int sum;
        while (scanf("%d",&n)==1)
        {
          long long sum=0;
          for (int i=1;i<=n;i++)
          {
            scanf("%d",&a[i].x);
            a[i].id=i;
            sum+=a[i].x;
          }
          if (sum%2)
          {
          printf("No
    ");
          continue;
          }
          printf("Yes
    ");
          sum/=2;
          sort(a+1,a+1+n,cmp);
          for (int i=1;i<=n;i++)
          {
            if (a[i].x<=sum)
            {ans[a[i].id]=1;
            sum-=a[i].x;
            }
            else
                ans[a[i].id]=-1;
          }
          printf("%d",ans[1]);
          for (int i=2;i<=n;i++)
            printf(" %d",ans[i]);
          cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    asp.net 内部重定向
    配置元素customErrors
    路由配置4-伪静态
    路由配置3
    路由配置2(转)
    ASP.NET实现图片防盗链(转)
    global中拦截404错误的实现方法
    使用一个HttpModule拦截Http请求,来检测页面刷新(F5或正常的请求)
    HttpApplication事件执行顺序(转)
    Android Studio NDK 新手教程(5)--Java对象的传递与改动
  • 原文地址:https://www.cnblogs.com/lqerio/p/9745588.html
Copyright © 2011-2022 走看看