zoukankan      html  css  js  c++  java
  • 【BZOJ3749】Łasuchy

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3749


    很好的一道DP题,非常锻炼思维,难想的不得了。

    定义dp[i][s]表示第i份食物的状态,0表示没有被选择,1表示被左边的人选择,2表示被右边的人选择,3表示被左右的人共同选择是否可行,若可行,则dp[i][s]表示i-1的状态。然后就可以进行转移了,对于每种状态的转移,都需要进行讨论,看是否满足条件,详见代码,建议画一下图,处理好条件。

    然后,因为这是个成环的DP,最后一个位置还会反过来更新第一个位置,所以我们需要枚举第一个位置的状态,看是否可行。

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 inline int get_num() {
     5     int num = 0;
     6     char c = getchar();
     7     while (c < '0' || c > '9') c = getchar();
     8     while (c >= '0' && c <= '9')
     9         num = num * 10 + c - '0', c = getchar();
    10     return num;
    11 }
    12 
    13 const int maxn = 1e6 + 5;
    14 
    15 int c[maxn], dp[maxn][4], ans[maxn];
    16 
    17 //~用于判断是否为-1
    18 inline void mov(int pre, int now) {
    19     if (~dp[pre][2] && c[pre] >= c[now]) dp[now][0] = 2;
    20     else if (~dp[pre][3] && c[pre] >= c[now] * 2) dp[now][0] = 3;
    21     if (~dp[pre][0] && c[pre] <= c[now]) dp[now][1] = 0;
    22     else if (~dp[pre][1] && c[pre] <= c[now] * 2) dp[now][1] = 1;
    23     if (~dp[pre][2] && c[pre] * 2 >= c[now]) dp[now][2] = 2;
    24     else if (~dp[pre][3] && c[pre] >= c[now]) dp[now][2] = 3;
    25     if (~dp[pre][0] && c[pre] * 2 <= c[now]) dp[now][3] = 0;
    26     else if (~dp[pre][1] && c[pre] <= c[now]) dp[now][3] = 1;
    27 }
    28 
    29 int main() {
    30     int n = get_num();
    31     for (int i = 1; i <= n; ++i)
    32         c[i] = get_num();
    33     for (int s = 0; s < 4; ++s) {
    34         memset(dp, -1, sizeof(dp));
    35         dp[1][s] = 4;
    36         for (int j = 2; j <= n; ++j) mov(j - 1, j);
    37         mov(n, 1);
    38         if (dp[1][s] != 4) {
    39             int p = dp[1][s];
    40             for (int i = n; i >= 1; --i) {
    41                 if (p == 1 || p == 3) ans[(i + n - 2) % n + 1] = i;
    42                 if (p == 2 || p == 3) ans[i] = i;
    43                 p = dp[i][p];
    44             }
    45             for (int i = 1; i <= n; ++i)
    46                 printf("%d ", ans[i]);
    47             return 0;
    48         }
    49     }
    50     printf("NIE");
    51     return 0;
    52 }
    AC代码
  • 相关阅读:
    struct pack unpack
    读书笔记 第四章&第五章
    The Sieve of Eratosthens(爱拉托逊斯筛选法)
    2013年3月百度之星A题
    2013年3月百度之星B题
    好句子
    BFS 与 DFS
    记录本
    HDU 2028 如何计算最小公倍数?
    HDU 2015 偶数求和 解题报告
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9898951.html
Copyright © 2011-2022 走看看