zoukankan      html  css  js  c++  java
  • 【NOIP2014】飞扬的小鸟

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1941


    怎么会有这么迷的一道题!

    明明思路很简单,但要想A掉,细节怎么就不好想呢!

    很显然的DP,状态一目了然,处理好特殊情况,一步步推就可以了。

    DP有刷表法和填表法,为了推的过程中特判是否到最高处省事,我选择了刷表法,80分,TLE了四个点,需要优化。超时主要是在于转移上,一个状态近似可以转移到m个状态,优化是当发现某次无法取得更优解,就剪枝,因为再往下肯定不会更优。而且需要从m到1枚举,可能这样会剪去更多的枝,好玄。。。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 inline int get_num() {
     8     int num = 0;
     9     char c = getchar();
    10     while (c < '0' || c > '9') c = getchar();
    11     while (c >= '0' && c <= '9')
    12         num = num * 10 + c - '0', c = getchar();
    13     return num;
    14 }
    15 
    16 const int maxn = 1e4 + 5, maxm = 1e3 + 5, inf = 0x3f3f3f3f;
    17 
    18 int tube[2][maxn], updown[2][maxn], dp[maxn][maxm];
    19 //0为下,1为上
    20 
    21 int main() {
    22     int n, m, k, ans = inf, cnta = 0, cntb = 0;
    23     n = get_num(), m = get_num(), k = get_num();
    24     for (int i = 0; i < n; ++i)
    25         updown[1][i] = get_num(), updown[0][i] = get_num();
    26     memset(tube[1], inf, sizeof(tube[1]));
    27     for (int i = 1; i <= k; ++i) {
    28         int p = get_num(), l = get_num(), h = get_num();
    29         tube[0][p] = l, tube[1][p] = h;
    30     }
    31     memset(dp, inf, sizeof(dp));
    32     memset(dp[0], 0, sizeof(dp[0]));
    33     for (int i = 0; i <= n; ++i)
    34         for (int j = m; j >= 0; --j) {
    35             if (dp[i][j] == inf) continue;
    36             if (i == n) {ans = min(ans, dp[i][j]); continue;}
    37             cnta = max(cnta, i);
    38             int next = j - updown[0][i], cnt;
    39             if (next > tube[0][i + 1] && next < tube[1][i + 1])
    40                 dp[i + 1][next] = min(dp[i + 1][next], dp[i][j]);
    41             next = j + updown[1][i], cnt = 1;
    42             if (next > m) next = m;
    43             while (next <= m) {
    44                 if (dp[i][j] + cnt > dp[i + 1][next]) break;
    45                 if (next > tube[0][i + 1] && next < tube[1][i + 1])
    46                     dp[i + 1][next] = min(dp[i + 1][next], dp[i][j] + cnt);
    47                 if (next == m) break;
    48                 next += updown[1][i], ++cnt;
    49                 if (next > m) next = m;
    50             }
    51         }
    52     if (ans < inf) printf("1
    %d", ans);
    53     else {
    54         for (int i = 0; i <= cnta; ++i)
    55             if (tube[1][i] < inf) ++cntb;
    56         printf("0
    %d", cntb);
    57     }
    58     return 0;
    59 }
    AC代码
  • 相关阅读:
    (82)zabbix如何选择适合的监控类型
    (80)zabbix性能优化中的几个建议
    (79)zabbix key总是not supported的解决方法
    (78)zabbix值缓存(value cache)说明
    Centos7搭建docker仓库
    centos7安装docker
    Win10调整MTU值
    nginx配置ssl证书
    CentOS7.6配置do.cker和K.B.S
    RAID阵列盘有一块状态变为外来处理方法
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9835363.html
Copyright © 2011-2022 走看看