问题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;
}