共鸣问题(牛客编程巅峰赛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] += z, a[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; } };