DP——P2300 合并神犇

题目背景

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 均为随机生成。

Solution:

  好久没写dp了啊,于是写一发dp。

  本题要使一段序列合并成不下降序列,因为只能合并相邻的两个数,所以合并后的一个数必定是由原版序列中的一段进行数次合并得到的。考虑简单的贪心思路,对于第一个数,每次不停加入一个数直到它们的和大于第一个数停止,继续此操作,直到结束,但是这样显然是错误的,因为前面满足了条件不一定后面会最优(很简单思考懒的举例了)。由贪心思路引申到dp,因为是一段合并,考虑到前缀和sum[i],我们令f[i]表示到了第i个数为止所合并的次数,用一个辅助数组maxp[i]表示到了i为止合并后最大的一个数,于是得到状态转移方程:if(sum[i]-sum[j]>=maxp[j])f[i]=f[j]+j-i-1(其中i>j)

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 inline int gi()
 5 {
 6     int a=0;char x=getchar();bool f=0;
 7     while((x<‘0‘||x>‘9‘)&&x!=‘-‘)x=getchar();
 8     if(x==‘-‘)x=getchar(),f=1;
 9     while(x>=‘0‘&&x<=‘9‘)a=a*10+x-48,x=getchar();
10     return f?-a:a;
11 }
12 ll n,sum[200005],f[200005],maxp[200005];
13 int main()
14 {
15     n=gi();int x,i,j;
16     for(i=1;i<=n;i++)x=gi(),sum[i]=sum[i-1]+x;
17     for(i=1;i<=n;i++){
18         for(j=i-1;j>=0;j--)
19         if(sum[i]-sum[j]>=maxp[j])break;
20         maxp[i]=sum[i]-sum[j];
21         f[i]=f[j]+i-j-1;maxp[i]=sum[i]-sum[j];
22     }
23     cout<<f[n];
24     return 0;
25 }

原文地址:https://www.cnblogs.com/five20/p/8419632.html

时间: 2024-08-05 18:08:31

DP——P2300 合并神犇的相关文章

P2300 合并神犇 DP

题目背景 loidc来到了NOI的赛场上,他在那里看到了好多神犇. 题目描述 神犇们现在正排成一排在刷题.每个神犇都有一个能力值p[i].loidc认为坐在附近的金牌爷能力参差不齐非常难受.于是loidc便想方设法对神犇们进行人道主义合并. loidc想把神犇的能力值排列成从左到右单调不减.他每次可以选择一个神犇,把他合并到两侧相邻的神犇上.合并后的新神犇能力值是以前两位犇的能力值之和.每次合并完成后,被合并的两个神犇就会消失.合并后的新神犇不能再分开(万一他俩有女朋友咋办)因此每次合并后神犇的

P2300 合并神犇(DP)

考虑这样一种分段策略,last表示合并到该位置的最小值,dp则表示最小次数 有一种特别的样例: 3 2 2 2 6 有以下两种合并策略: 3 6 6 3 4 8 虽然合并次数相同,但是考虑到对后面的序列的影响的时候,选取3 6 6显然是更优的 因为他尽量保证了最大值不要太大,尽可能减少后面部分需要的合并次数 那么dp方程就很容易搞出来了: dp[i]=min{dp[j]+i-j-1}(sum[i]-sum[j]>=last[j]) 这代表合并[j+1,i]这个区间里的所有数字 用单调队列维护这个

合并神犇

题目背景 loidc来到了NOI的赛场上,他在那里看到了好多神犇. 题目描述 神犇们现在正排成一排在刷题.每个神犇都有一个能力值p[i].loidc认为坐在附近的金牌爷能力参差不齐非常难受.于是loidc便想方设法对神犇们进行人道主义合并. loidc想把神犇的能力值排列成从左到右单调不减.他每次可以选择一个神犇,把他合并到两侧相邻的神犇上.合并后的新神犇能力值是以前两位犇的能力值之和.每次合并完成后,被合并的两个神犇就会消失.合并后的新神犇不能再分开(万一他俩有女朋友咋办)因此每次合并后神犇的

P2456 - 膜拜神犇

P2456 - 膜拜神犇 Description 有一个 n 个点 m 条边的有向图, 蒟蒻可以从 1 号点出发在图上走, 并且最终需要回到 1 号点. 每个点都有一个神犇( 包括 1 号点), 每次经过一个没到过的点, 蒟蒻都会膜拜那位 神犇. 蒟蒻希望膜拜尽可能多的神犇. 由于蒟蒻膜拜神犇的欲望非常强烈, 所以他可以有一次机会逆着一条有向边的方向走. ( 需要注意的是, 这条边的方向不会改变). 你现在想知道, 蒟蒻最多能膜拜多少神犇? Input 第一行 2 个整数 n. m, 分别表示图

cogs 1656. 膜拜神犇

1656. 膜拜神犇 ★☆   输入文件:trioxorz.in   输出文件:trioxorz.out   简单对比时间限制:0.5 s   内存限制:128 MB [题目描述] bigmingod 是F.M.S信息组的组草,同时也是万人膜拜的神犇,整个年级暗恋他的女生不计其数,这让机房里的三只蒟蒻QYHDS,LZK,OIdiot羡慕嫉妒恨.为了获得像bigmingod一样的成就,这三只蒟蒻决定每次竞赛课前对他进行膜拜--三个人构成一个三角形,将bigmingod包围在内部(不包括边上),称为

【BZOJ4916】神犇和蒟蒻 杜教筛

[BZOJ4916]神犇和蒟蒻 Description 很久很久以前,有一只神犇叫yzy; 很久很久之后,有一只蒟蒻叫lty; Input 请你读入一个整数N;1<=N<=1E9,A.B模1E9+7; Output 请你输出一个整数A=\sum_{i=1}^N{\mu (i^2)}; 请你输出一个整数B=\sum_{i=1}^N{\varphi (i^2)}; Sample Input 1 Sample Output 1 1 题解:哎?上面的那个东西好像一直是1?(废话),然后 设j=i/d,

bzoj4916 神犇和蒟蒻

Description 很久很久以前,有一只神犇叫yzy; 很久很久之后,有一只蒟蒻叫lty; Input 请你读入一个整数N;1<=N<=1E9,A.B模1E9+7; Output 请你输出一个整数A=\sum_{i=1}^N{\mu (i^2)}; 请你输出一个整数B=\sum_{i=1}^N{\varphi (i^2)}; Sample Input 1 Sample Output 1 1 正解:杜教筛. 第一问答案是$1$. 第二问,先给个结论:$\varphi (n^{2})=n\va

[FZYZOJ 2132] Zrn神犇之一起来看流星雨

P2132 -- Zrn神犇之一起来看流星雨 时间限制:1000MS 内存限制:131072KB Description Zrn神犇带着妹纸来到异度空间看流星雨. 那儿有个矩形的星盘,一共有N*M格,流星雨都会落在那里.只是,那里的流星雨很奇特,都是很有节奏地.成排成排地落下的.每个时刻都会落下一排的流星,它们落在星盘上,形成了一个一个星群. 而Zrn神犇和妹纸对于星群的定义是不一样的.Zrn神犇认为,一颗星星和它周围的四个格子里的星星属于同一个星群.而妹纸认为,一颗星星和它周围的八个格子里的星

[FZYZOJ 2162] Zrn神犇之折纸游戏

P2162 -- Zrn神犇之折纸游戏 时间限制:2000MS 内存限制:524288KB Description Zrn神犇最近喜欢上一款折纸游戏,因此他几乎每天都拿着一条悠长悠长又寂寥的纸带折来折去.其具体规则是这样的: 这是一个长度为N,宽度为1的纸条,从1开始写着连续的N个自然数. 1 2 3 4 5 6 … N 如果它的长度为偶数,Zrn神犇则会很高兴,直接把它从左往右或从右往左对折.比如长度为6的纸条从左往右对折完就会是这样: 如果它的长度为质数,Zrn神犇则会觉得不太爽,他就只能把