hdu~2217(简单dp)

5 篇文章 0 订阅

visit

题意:在x轴上,出发点在0的位置,给你一些其他点的位置,求在规定时间内能遍历最多的点的个数。

其实个人觉得不会dp的人也能做,说是dp也算不上。

以0为起点,负半轴为左边。

1.先开两个数组l[],r[]存左右两边各点到0的距离。

2.再开两个数组lm[],rm[]存以上述各点为拐点能遍历的最多点的个数。


具体的还是看代码好理解:

<span style="font-size:18px;">#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int cmp(const void *a,const void *b)
{
    return *(int *)a-*(int *)b;
}
int fmax(int a,int b)
{
    return a>b?a:b;
}

int main()
{
    int n,t,x,li,ri,sum;
    int l[2005],r[2005];    //记录左右两边到0点距离大小
    int lm[2005],rm[2005];  //记录以i为拐点能遍历的最多点数
    while(scanf("%d %d",&n,&t)!=EOF)
    {
        memset(lm,0,sizeof(lm));
        memset(rm,0,sizeof(rm));
        ri=0,li=0,sum=0;
        l[0]=r[0]=0;
        for(int i=1;i<=n;i++)   //生成l[],r[],记录点为0的个数
        {
            scanf("%d",&x);
            if(x<0)
                l[++li]=-x;
            else if(x>0)
                r[++ri]=x;
            else
                sum++;
        }
        qsort(&l[1],li,sizeof(int ),cmp);   //升序排序
        qsort(&r[1],ri,sizeof(int ),cmp);

        for(int i=1;i<=li;i++)      //先从左边走
        {       
            int k=i;                //以i为拐点,至少得走到i点
            for(int j=1;j<=ri;j++)
            {
                if(l[i]*2+r[j]<=t)  //走到左边第i个再走到右边第j个所花时间
                    lm[i]=++k;      
                else                
                    break;
            }
        }

        for(int i=1;i<=ri;i++)      //走右边走,同上
        {
            int k=i;
            for(int j=1;j<=li;j++)
            {
                if(l[j]+r[i]*2<=t)
                    rm[i]=++k;
                else
                    break;
            }
        }
        int max=0;
        for(int i=1;i<=li;i++)  //若不拐,从两边走能遍历最多点数
            if(l[i]<=t)
                max=i;
        for(int i=max;i<=ri;i++)
            if(r[i]<=t)
                max=i;
                
        for(int i=1;i<=li;i++)  //若拐弯,能遍历最大点数
            max=fmax(max,lm[i]);
        for(int i=1;i<=ri;i++)
            max=fmax(max,rm[i]);
        printf("%d\n",max+sum);
    }
    return 0;
}
</span>





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值