zoukankan      html  css  js  c++  java
  • hlg1186青蛙过河【dp】

    题意:在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是s到t之间的任意正整数(包括s,t)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。

    题目给出独木桥的长度L,青蛙跳跃的距离范围s,t,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

    分析:

    dp[i]代表从i位置到达终点最少的石子数  然后往前dp即可

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 const int maxn = 100005;
     7 const int INF = 1000000000;
     8 int dp[maxn];
     9 int a[maxn];
    10 
    11 int main() {
    12     int l, s, t, n;
    13     int d;
    14     while(EOF != scanf("%d %d %d %d",&l, &s, &t, &n) ) {
    15         memset(a, 0, sizeof(a));
    16         for(int i = 1; i <= n; i++) {
    17             scanf("%d",&d);
    18             a[d] = 1;
    19         }
    20         memset(dp, 0x35, sizeof(dp));
    21         dp[l] = 0;
    22         for(int i = l - 1; i >= 0; i--) {
    23             for(int j = i + s; j <= i + t; j++) {
    24                 if(j >= l) {
    25                     if(a[i]) {
    26                         dp[i] = 1;
    27                     } else {
    28                         dp[i] = 0;
    29                     }
    30                 } else {
    31                     if(a[i]) {
    32                         dp[i] = min(dp[i], dp[j] + 1);
    33                     } else {
    34                         dp[i] = min(dp[i], dp[j]);
    35                     }
    36                 }
    37             }
    38         }
    39         printf("%d
    ", dp[0]);
    40     }
    41     return 0;
    42 }
    View Code

    /////////////////////////////////////////////////////////

    今天我从前往后dp了一下  然后直接被wa了

     1 memset(dp, 0x35, sizeof(dp));
     2         dp[0] = 0;
     3         for(int i = 1; i <= l; i++) {
     4             for(int j = s; j <= t; j++) {
     5                 int x  = i - j;
     6                 if(x >= 0) {
     7                     if(a[i]) {
     8                         dp[i] = min(dp[x] + 1, dp[i]);
     9                     } else {
    10                         dp[i] = min(dp[x], dp[i]);
    11                     }
    12                 }
    13             }
    14         }
    15 //        for(int i = 0; i <= l; i++) {
    16 //            printf("%d ", dp[i]);
    17 //        } puts("");
    18         printf("%d
    ", dp[l]);

    以上以上是wa的代码

    我很快意识到了自己错哪了  

    就是可能最后的结果不是dp[l]和有可能跳过  

    于是改成了这个

     1 memset(dp, 0x3f, sizeof(dp));
     2         dp[0] = 0;
     3         for(int i = 1; i <= l; i++) {
     4             for(int j = s; j <= t; j++) {
     5                 int x  = i - j;
     6                 if(x >= 0) {
     7                     if(a[i]) {
     8                         dp[i] = min(dp[x] + 1, dp[i]);
     9                     } else {
    10                         dp[i] = min(dp[x], dp[i]);
    11                     }
    12                 }
    13             }
    14         }
    15 //        for(int i = 0; i <= l; i++) {
    16 //            printf("%d ", dp[i]);
    17 //        } puts("");
    18         int ans = 1000000000;
    19         for(int i = l; i < l + t; i++) {
    20             ans = min(ans, dp[i]);
    21         }
    22         printf("%d
    ", ans);

    然后又wa了   于是继续找

    突然我觉得自己把自己坑了   

    上一个错误只找了l之后的dp但是计算的过程中l之后的dp都没有进行计算  

    于是  

    ac代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 const int maxn = 100015;
     7 const int INF = 1000000000;
     8 int dp[maxn];
     9 int a[maxn];
    10 
    11 int main() {
    12     int l, s, t, n;
    13     int d;
    14     while(EOF != scanf("%d %d %d %d",&l, &s, &t, &n) ) {
    15         memset(a, 0, sizeof(a));
    16         for(int i = 1; i <= n; i++) {
    17             scanf("%d",&d);
    18             a[d] = 1;
    19         }
    20         memset(dp, 0x3f, sizeof(dp));
    21         dp[0] = 0;
    22         for(int i = 1; i < l + t; i++) {
    23             for(int j = s; j <= t; j++) {
    24                 int x  = i - j;
    25                 if(x >= 0) {
    26                     if(a[i]) {
    27                         dp[i] = min(dp[x] + 1, dp[i]);
    28                     } else {
    29                         dp[i] = min(dp[x], dp[i]);
    30                     }
    31                 }
    32             }
    33         }
    34         int ans = 1000000000;
    35         for(int i = l; i < l + t; i++) {
    36             ans = min(ans, dp[i]);
    37         }
    38         printf("%d
    ", ans);
    39     }
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    mac下用xattr命令来删除文件的扩展属性
    使用vue.js实现checkbox的全选和多个的删除功能
    正则表达式匹配任意字符(包括换行符)的写法
    jQuery Mobile动态刷新页面样式
    jquery mobile各类标签的refresh
    jQuery .attr()和.removeAttr()方法操作元素属性示例
    jquery mobile各类组件刷新方法
    Apache PDFbox开发指南之PDF文档读取
    日期字符串解析--SimpleDateFormat严格限制日期转换setLenient(false)
    hdu5032 Always Cook Mushroom
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/4314281.html
Copyright © 2011-2022 走看看