zoukankan      html  css  js  c++  java
  • bzoj 2563: 阿狸和桃子的游戏

    Description

      阿狸和桃子正在玩一个游戏,游戏是在一个带权图G=(V, E)上进行的,设节点权值为w(v),边权为c(e)。游戏规则是这样的:
      1. 阿狸和桃子轮流将图中的顶点染色,阿狸会将顶点染成红色,桃子会将顶点染成粉色。已经被染过色的点不能再染了,而且每一轮都必须给一个且仅一个顶点染色。
      2. 为了保证公平性,节点的个数N为偶数。
      3. 经过N/2轮游戏之后,两人都得到了一个顶点集合。对于顶点集合S,得分计算方式为

      由于阿狸石头剪子布输给了桃子,所以桃子先染色。两人都想要使自己的分数比对方多,且多得越多越好。如果两人都是采用最优策略的,求最终桃子的分数减去阿狸的分数。

    solution

    正解:贪心
    我们分析对答案的贡献,也就是对差的贡献,我们将边权拆成w/2,分别加到边对应的两个节点中,按照点权排序分别取,最后就是答案
    分析为什么这样是对的:首先我们选择了一个点i,假设i对应的边边权为正无穷,考虑次大点j,如果阿狸选择j,那么就会失去i的边权,显然不是更优的,所以会选择另一条边,所以所有情况都能作出正确决策,满足最优性,所以就是答案

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    double w[10005];
    void work()
    {
       int x,y,z,n,m;cin>>n>>m;
       for(int i=1;i<=n;i++)scanf("%lf",&w[i]);
       for(int i=1;i<=m;i++){
          scanf("%d%d%d",&x,&y,&z);
          w[x]+=z/2.0;w[y]+=z/2.0;
       }
       sort(w+1,w+n+1);
       double s=0;int t=1;
       for(int i=n;i>=1;i--)
          s+=t*w[i],t*=-1;
       printf("%.lf
    ",s);
    }
     
    int main()
    {
        work();
        return 0;
    }
    
  • 相关阅读:
    ECMAScript 6 字符串的扩展
    iOS蓝牙开发
    PhotoKit type类型
    HealthKit详解
    苹果证书签名机制
    小程序事件传递
    小程序跳转界面传可变参数
    小程序获取openId
    小程序发起post请求回调成功没有数据
    主干发布和分支发布
  • 原文地址:https://www.cnblogs.com/Hxymmm/p/7712716.html
Copyright © 2011-2022 走看看