共鸣问题(牛客编程巅峰赛S2第12场 - 青铜&白银&黄金 )

题目描述

  现在有n个音符和m对共鸣关系,编号为1~n,每个音符自己有一个奏响时的优美程度,共鸣关系(x,y,z)表示音符x和y同时奏响的额外优美程度是z,同时不奏响则为-z,其他情况为0。音符可以选择奏响或者不奏响,不奏响的音符没有优美程度。我们想知道最大的优美程度和是多少,我们不需要知道具体是哪些音符被奏响了,只需输出最大和即可。
共鸣关系可能有重复,其共鸣效果也会重复叠加。

示例

输入

  2,1,[-10,-10],[[1,2,5]]

输出

  -5

备注

  数据包括两个数n,m,一个长度为n的数组a[],表示每个音符奏响时的优美程度(a[0]表示第一个音符),一个第一维长度为m的二维数组,描述m组共鸣关系。
  输出一个整数表示答案。
  n,m<=100000,所有的优美程度和额外优美程度的绝对值<=33000

思路&&感想

  这是一道思维题,奈何我一开始没读懂

  具体做法大概是:

  首先将答案减去给出的所有共鸣条件 (x,y,z)(x,y,z) 的权值 z

  然后再让给出的共鸣条件的 a[x] += za[y] += z

  现在这个转化是没有问题的。

  因为你选择 a[x],a[y]中的一个,相当于抵消掉了减去的 z ,这时候获得的额外权值就是0

  倘若 a[x],a[y]两个都不选,相当于最后获得的答案权值就是 -z

  倘若 a[x],a[y]两个都选择,相当于最后获得的答案权值就是 z

  那么这时候,我们就把问题转化了。现在就是问在当前的 a[]序列中选出一些数使得和最大,允许不选,不选即和为0。

  然后简单贪心可以知道,我们只取 a[]序列中 大于 0 的即可(等于 0 的爱取不取)

  然后这道题就做完了。

AC代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 
     * @param m int整型 
     * @param a int整型vector 
     * @param b int整型vector<vector<>> 
     * @return long长整型
     */
    long long wwork(int n, int m, vector<int>& a, vector<vector<int> >& b) {
        long long c[100010],ans=0;
        for(int i=0;i<n;i++) c[i+1]=a[i];
        for(int i=0;i<m;i++)
        {
            c[b[i][0]]+=b[i][2];
            c[b[i][1]]+=b[i][2];
            ans-=b[i][2];
        }
        for(int i=1;i<=n;i++)
        {
            if(c[i]>0) ans+=c[i];
        }
        return ans;
    }
};

 

posted @ 2020-12-24 12:16  TheWeak  阅读(55)  评论(0编辑  收藏  举报