链接:https://ac.nowcoder.com/acm/contest/10324/C
来源:牛客网
题目描述
现在有n个音符和m对共鸣关系,编号为1~n,每个音符自己有一个奏响时的优美程度,共鸣关系(x,y,z)表示音符x和y同时奏响的额外优美程度是z,同时不奏响则为-z,其他情况为0。
音符可以选择奏响或者不奏响,不奏响的音符没有优美程度。我们想知道最大的优美程度和是多少,我们不需要知道具体是哪些音符被奏响了,只需输出最大和即可。
共鸣关系可能有重复,其共鸣效果也会重复叠加。
数据包括两个数n,m,一个长度为n的数组a[],表示每个音符奏响时的优美程度(a[0]表示第一个音符),一个第一维长度为m的二维数组,描述m组共鸣关系。
输出一个整数表示答案。
n,m<=100000,所有的优美程度和额外优美程度的绝对值<=33000
示例输入:
2,1,[-10,-10],[[1,2,5]]
示例输出:
-5
分析
最开始,以为是一个动态规划的题,有一说一,他长得确实像动态规划。
对于第i个音符,选择演奏还是不演奏,然后要附加考虑到共鸣的问题。
感觉很复杂,不会做。
后来经过讲解才知道,不需要动态规划。
我们先不考虑共鸣的问题,那么就是直接贪心,如果第i个音符是正的,就演奏,是负数,就不演奏,很简单。
那么考虑共鸣,对于共鸣关系(x,y,z)来说,一共可能出现四种情况,其额外优美程度题目也已经给出:
- x演奏,y演奏 z
- x不演奏,y演奏 0
- x演奏,y不演奏 0
- x不演奏,y不演奏 -z
思考的关键就在于这四种情况,如果我们假设都不演奏,那么我们的额外优美程度是-z,演奏任意一个,都会变成0,两个的话就是z。
所以可以直接把z这个值直接加到x,y音符上:
- 默认不演奏为-z。
- 演奏x,那么值为-z+z=0
- 演奏y,那么值为-z+z=0
- 都演奏,-z+z+z=z
这样我们就把共鸣关系的值给分配到音符上了,然后直接对每个音符贪心即可。
代码
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 ans=0;
vector<long long> c(a.begin(),a.end());
for (int i=0; i<m; i++){
c[b[i][0]-1]+=b[i][2];
c[b[i][1]-1]+=b[i][2];
ans-=b[i][2];
}
for (int i=0; i<n; i++){
if (c[i]>0) ans+=c[i];
}
return ans;
}
};
要注意,最后的答案可能爆int,要开long long。