Evolution Game【dp】

         

问题C:进化游戏

时间限制: 1秒   内存限制: 128 MB 
提交: 309   解决: 58 
提交 ] [ 状态 ] [命题人:admin ]

题目描述

在ICPC的幻想世界中,有神奇的野兽。随着它们的成长,这些野兽可以改变形态,每次它们变得更强大。但野兽不能完全随意改变形态。在每种形式中,野兽都有n只眼睛和k角,这些影响它可以做出的变化。  野兽只能变成比现在更多的角。 野兽只能变成最多只有眼睛差异的形态。因此,如果野兽目前有眼睛,它可以改变为眼睛在[n - w,n + w]范围内的形式。 
 


  
对于1到N之间的每个眼睛,野兽都有一种形式,这些形状也会有相应数量的角。野兽可以以任何形式出生。问题是,这些野兽之一变得多么强大?换句话说,在可能性消失之前,野兽会改变多少次? 

 

输入

第一行包含两个整数N和w,分别表示最大眼数和变化中允许的最大眼差(1≤N≤5000;0≤w≤N)。  
下一行包含N个整数,表示每种形式的喇叭数。即第i个数字,h(i),是我眼睛形状的角数(1≤h(i)≤1000 000)。 

 

输出

对于每个测试用例,显示包含最大可能更改次数的一行。 

 

样例输入

复制样例数据

5 2

1 2 2 2 7

样例输出

2

提示

从1个角和4个眼睛开始,它可以改变4次:( 1个角4个眼睛) - >(2个角3个眼睛) - >(3个角2个眼睛) - >(4个角5个眼睛) - >(5个角1只眼睛)。


题意:

        根据角的数量从小到大 “成长”,判断根据满足眼睛数量的一个区间上的最大次数

题解:

       根据动态规划的思想,从后往前更新最大值,找到所有节点中最大的那个变换次数

 

代码:

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<set>
const double PI=acos(-1);
typedef long long ll;
const int INF=1e9+7;
const int xmax=2e6+10007;
const int xmin=-1e6+7;
using namespace std;
int ans=-1;
int tmp;
int l,r;
int n,w;
struct node
{
    int e;
    int h;
    int len;    ///存每个结点的最大变换次数
} b[151007];
bool cmp(node x,node y)
{
    return x.h<y.h;
}
/*5 2
1 2 2 2 7*/

int main()
{
    scanf("%d%d",&n,&w);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&b[i].h);
        b[i].e=i;
    }
    sort(b+1,b+n+1,cmp);
    for(int i=n;i>=1;i--)   ///逆向遍历,更新最优解
    {
        tmp=-1;
        l=b[i].e-w;r=b[i].e+w;  ///i结点的左右能到达的边界
        for(int j=i+1;j<=n;j++)
        {
             ///注意严格递增,然后循环找出i之后的最大值来
            if(b[j].e>=l&&b[j].e<=r&&b[j].h>b[i].h&&b[j].len>tmp)  
            {
                tmp=b[j].len;
            }
        }
        if(tmp>=0)      ///如果找到解,就得对i结点的len加一
            b[i].len=tmp+1;
    }
    int maxx=b[1].len;      ///找到所有结点的最大值
    for(int i=2;i<=n;i++)
        maxx=max(maxx,b[i].len);
    printf("%d\n",maxx);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值