• boj1074_Candy的魔法


    Candy的魔法 Submit: 830   Accepted:178 Time Limit: 1000MS  Memory Limit: 65536KDescription
    小蚂蚁的家在X轴的原点上,他的学校在X轴的N点上。
    小蚂蚁从家里出发,沿X轴正方向前进(不能往回走),去学校里上课,他的本能速度是每两秒一个单位。由于小蚂蚁的速度之慢,老师担心他会迟到,就在途中的某些点上放了具有魔法的糖果(每个位置要么没放,要么只放了一个),每个糖果有一定的魔法值b,他能使小蚂蚁将以每秒1个单位的速度移动b秒,在这个魔法期间之内它只能向前移动,不能停下,也不能吃其他糖果。当然了,小蚂蚁可以自己选择是否要吃糖果,以及吃哪些位置上的糖果。他也只能朝向学校的方向走,而不能掉头。
    现在给出你学校的位置N,以及糖果的放置情况,请你计算小蚂蚁到达学校至少需要多久。
    Input
    多组数据测试。数据以两个0结束输入。
    每组数据包括两部分:第一行两个整数N(1< N <= 1000000000),M(0 <= M <= 50),N为学校的位置,M表示老师在途中放置的糖果的数目;
    接下来的M行里,每行两个整数a(1<= a <= N),b(1<=b<=10000),a表示糖果位置,b表示对应糖果的魔法值。
    Output
    对每一组测试输出,输出小蚂蚁至少需要多少时间才能到达学校。每组数据的输出应该占一行。
    Sample Input
    7 2
    2 2
    3 4
    5 3
    3 1
    1 2
    4 2
    0 0
    Sample Output
    10
    7

    View Code
     1 #include<iostream>
    2 using namespace std;
    3 typedef struct candy{
    4 int a;
    5 int b;
    6 }candy;
    7 bool cmp(const candy &x, const candy &y); //用STL的sort()排序,acm常用快攻利器
    8 bool get_dest(int ,int ,int );
    9 int mymin(int ,int );
    10
    11 int dp[50]; //设dp[i]为从这点开始(即前面没有candy),到达终点的最短时间。
    12 candy c[50];
    13 int main()
    14 {
    15 int N;
    16 int M,i;
    17 while(1)
    18 {
    19 scanf("%d%d",&N,&M);
    20 if(N==0 && M==0) break;
    21 if(M==0)
    22 {
    23 printf("%d\n",2*N);
    24 continue;
    25 }
    26 memset(dp,0,sizeof(dp));
    27 for(i=0;i<M;i++)
    28 scanf("%d%d",&c[i].a,&c[i].b);
    29
    30 sort(c,c+M,cmp);
    31 if(get_dest(c[M-1].a,c[M-1].b,N)) dp[M-1]=2*c[M-1].a+2*(N-c[M-1].a-c[M-1].b)+c[M-1].b; //从后面往前dp,最后一点能到达恰好能终点
    32 else dp[M-1]=2*N; //最后一点到达不到终点
    33
    34 for(i=M-2;i>=0;i--)
    35 {
    36 if(!get_dest(c[i].a,c[i].b,N)) dp[i]=dp[i+1]; //当前点到达不了终点
    37 else //当前点可以到达终点
    38 {
    39 int uneat=dp[i+1]; //不吃这点
    40 int eat=-1; //吃这点
    41 for(int k=i+1;k<M;k++) //考虑吃了这点后的后续点
    42 {
    43 if( (c[i].a+c[i].b)<=c[k].a )
    44 {
    45 eat=dp[k]-c[i].b;
    46 break;
    47 }
    48 }
    49 if(eat==-1) eat=2*c[i].a+c[i].b+2*(N-c[i].a-c[i].b);
    50 dp[i]=mymin(eat,uneat);
    51 }
    52 }
    53
    54 printf("%d\n",dp[0]);
    55 }
    56 system("pause");
    57 return 0;
    58 }
    59
    60 bool cmp(const candy &x, const candy &y)
    61 {
    62 return x.a<y.a;
    63 }
    64 bool get_dest(int a,int b,int c)
    65 {
    66 if((a+b)>c) return false;
    67 else return true;
    68 }
    69 int mymin(int a,int b)
    70 {
    71 return (a<=b)?a:b;
    72 }

     

    //这道题是从5月份开到的,一直到现在才ac,当然中间的时间没有思考。之前一直都是考虑从前面往后面dp,但一直都想不出思路。换一个角度就好了,从后面往前dp,呵呵!

  • 相关阅读:
    Beginning SDL 2.0(5) 基于MFC和SDL的YuvPlayer
    Beginning SDL 2.0(6) 音频渲染及wav播放
    Beginning SDL 2.0(4) YUV加载及渲染
    Beginning SDL 2.0(3) SDL介绍及BMP渲染
    获取windows可执行文件的version信息(版本号)
    visual studio 2005提示脚本错误 /VC/VCWizards/2052/Common.js
    Beginning SDL 2.0(2) TwinklebearDev SDL 2.0 Tutorial
    Beginning SDL 2.0(1) SDL功能简介
    ffmpeg与H264编码指南
    2015-07学习总结——网络编程(TCP/IP)
  • 原文地址:https://www.cnblogs.com/winterIce/p/boj1074.html
Copyright © 2020-2023  润新知