bzoj1345(区间合并式的贪心)

来源:互联网 发布:人工智能教学百度云 编辑:程序博客网 时间:2024/06/08 07:35

此题倒着想就好了,从最大那个数开始,这个数对答案的贡献一定最多是2*这个数,因为他还有阔能是边界,然后让这个数做一棵树的根,然后再按照同样的方法处理他两边的哪些数,最后形成一颗树,数列中如果某个数的两边都是比他大的数那么他一定是叶子,叶子对答案的贡献是0,其他情况都不是,对于不是叶子的数,有几个儿子那他对答案的贡献就是儿子数乘以他本身,他最多2个儿子注意。因为一个数是不阔能参与三次合并的(在所有数都不同的情况下)。

最后我们再处理一下一些连续的数都是相同的就好了。

中和上述就是:

先处理相同的连续的一些数。

然后每个数比较两边,那么ans+=(a[i-1]<a[i]?1:0)*a[i]+(a[i+1]<a[i]?1:0)*a[i];

其实有点像poj3253只不过这题思维难度大点。

好慢~~~~

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int a[2000000];int main(){int n;scanf("%d", &n);long long ans = 0; int tot = 1;for (int i = 0; i < n; i++){scanf("%d", &a[i]);if (i > 0){if (a[i] == a[tot - 1])ans += a[i];elsea[tot++] = a[i];}}if (tot == 1)printf("%lld\n", ans);else{if (a[0] > a[1])ans += a[0];if (a[tot- 1] > a[tot - 2])ans += a[tot - 1];for (int i = 1; i < tot - 1; i++){if (a[i]>a[i - 1])ans += a[i];if (a[i] > a[i + 1])ans += a[i];}printf("%lld\n", ans);}return 0;}


原创粉丝点击