zoukankan      html  css  js  c++  java
  • P2300 合并神犇 DP

    题目背景

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


     

    这题大家的第一印象大概都是贪心,但是我们的熊本熊在洛谷的题解中给出了反例,而正解是DP。

    f[i]表示前i个数最小要花费多少次达到要求,

    pre[i]表示前i个数中最大的数,

    于是我们就有了下面的代码(如有雷同,纯属故意)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define il inline
    #define ll long long
    #define db double
    using namespace std;
    il ll gl()
    {
    	int x=0,y=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9')
    		{
    			if(ch=='-')
    				y=-1;
    			ch=getchar();
    		}
    	while(ch>='0'&&ch<='9')
    		{
    			x=x*10+ch-'0';
    			ch=getchar();
    		}
    	return x*y;
    }
    ll sum[200045];
    ll f[200045];
    ll pre[200045];
    int main()
    {
    	int n;
    	cin>>n;
    	ll x;
    	for(int i=1;i<=n;i++)
    		{
    			x=gl();
    			sum[i]=sum[i-1]+x;
    		}
    	for(int i=1;i<=n;i++)
    		{
    			int j;
    			for(j=i-1;j>=0;j--)
    				if(sum[i]-sum[j]>=pre[j])
    					break;
    			f[i]=f[j]+i-j-1;
    			pre[i]=sum[i]-sum[j];
    		}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
    PEACE
  • 相关阅读:
    jmeter的基本功能使用详解
    服务器资源监控插件(jmeter)
    前端技术之--CSS
    前端技术之--HTML
    TCP/IP基础知识
    TCP/IP、Http的区别
    关于性能调优
    如何修改Docker已运行实例的端口映射
    Mysql 主从同步配置
    Presto的基本概念
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7491637.html
Copyright © 2011-2022 走看看