合并神犇

Posted Z-Y-Y-S

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并神犇相关的知识,希望对你有一定的参考价值。

题目背景

loidc来到了NOI的赛场上,他在那里看到了好多神犇。

题目描述

神犇们现在正排成一排在刷题。每个神犇都有一个能力值p[i]。loidc认为坐在附近的金牌爷能力参差不齐非常难受。于是loidc便想方设法对神犇们进行人道主义合并。

loidc想把神犇的能力值排列成从左到右单调不减。他每次可以选择一个神犇,把他合并到两侧相邻的神犇上。合并后的新神犇能力值是以前两位犇的能力值之和。每次合并完成后,被合并的两个神犇就会消失。合并后的新神犇不能再分开(万一他俩有女朋友咋办)因此每次合并后神犇的总数会减1.

loidc想知道,想治好他的强迫症需要合并多少次

输入输出格式

输入格式:

第一行一个整数 n。

第二行 n 个整数,第 i 个整数表示 p[i]。

输出格式:

loidc需要合并的次数

输入输出样例

输入样例#1:
8
1 9 9 4 1 2 2 9
输出样例#1:
3

说明

对于 50%的数据,0< n <=5000。

对于 100%的数据,0< n <=200000,0< p[i] <=2147483647,p 均为随机生成。

n^2水过

f[i]为第1~i位合并的次数

pre[i]为第1~i位最末尾的数

j为满足sum[i]-sum[j]>=pre[j]的最大数

f[i]=f[j]+i-j-1

pre[i]=sum[i]-sum[j]

显然pre[i]越小越好,这样找到一个就可以退出

正好数据很水

复杂度强迫症硬是想nlogn可以套一个平衡树

或者写一个二分

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int f[200001],n;
 7 long long sum[200001],pre[200001];
 8 int main()
 9 {int i,j;
10   cin>>n;
11   for (i=1;i<=n;i++)
12     {
13       scanf("%lld",&sum[i]);
14       sum[i]+=sum[i-1];
15     }
16   for (i=1;i<=n;i++)
17     {
18       for (j=i-1;j>=0;j--)
19     {
20       if (sum[i]-sum[j]>=pre[j])
21         break;
22     }
23       f[i]=f[j]+i-j-1;
24       pre[i]=sum[i]-sum[j];
25     }
26   cout<<f[n];
27 }

 

以上是关于合并神犇的主要内容,如果未能解决你的问题,请参考以下文章

P2300 合并神犇(DP)

P2300 合并神犇(单调队列优化dp)

luogu P2300 合并韩雨辰神犇

4.3 合并重复的条件执行片段

Python代码阅读(第19篇):合并多个字典

线段树区间合并POJ3667-Hotel