luogu P1941 飞扬的小鸟

Posted ZlycerQan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1941 飞扬的小鸟相关的知识,希望对你有一定的参考价值。

二次联通门 : luogu P1941 飞扬的小鸟

 

 

 

 

/*
    luogu P1941 飞扬的小鸟

    dp
    向上飞是完全背包,向下掉就是01背包
    分情况讨论一下
    最后合并一下
*/
#include <cstdio>
#include <iostream>
#include <cstring>

const int BUF = 123123123;
char Buf[BUF], *buf = Buf;

inline void read (int &now)
{
    for (now = 0; !isdigit (*buf); ++ buf);
    for (; isdigit (*buf); now = now * 10 + *buf - 0, ++ buf);
}
#define Max 10010

int x[Max], y[Max], dp[Max][Max / 10];
int up[Max], down[Max];

inline int min (int a, int b)
{
    return a < b ? a : b;
}

int Main ()
{
    freopen ("bird.in", "r", stdin);
    freopen ("bird.ans", "w", stdout);
    fread (buf, 1, BUF, stdin);    
    register int i, j, k; int N, M, K; read (N), read (M), read (K);
    int z; memset (dp, 0x3f, sizeof dp); int Count, Answer;
    for (i = 1; i <= M; ++ i) dp[0][i] = 0;
    for (i = 1; i <= N; ++ i) up[i] = M + 1;
    for (i = 0; i < N; ++ i)
        read (x[i]), read (y[i]);
    for (i = 1; i <= K; ++ i)
        read (z), read (down[z]), read (up[z]);
    long long INF = dp[0][0];
    for (i = 1; i <= N; ++ i)
    {
        for (j = 1; j <= M; ++ j)
        {
            if (j > x[i - 1])
            {
                dp[i][j] = min (dp[i][j], dp[i - 1][j - x[i - 1]] + 1);
                dp[i][j] = min (dp[i][j], dp[i][j - x[i - 1]] + 1);
            }
            if (j == M)
                for (k = j - (i - 1)[x]; k <= M; ++ k)
                {
                    dp[i][j] = min (dp[i][j], dp[i - 1][k] + 1);
                    dp[i][j] = min (dp[i][j], dp[i][k] + 1);
                }
        }
        for (j = down[i] + 1; j <= up[i] - 1; ++ j)
            if (j + (i - 1)[y] <= M)
                dp[i][j] = min (dp[i][j], dp[i - 1][j + (i - 1)[y]]);
        for (j = 1; j <= down[i]; ++ j) dp[i][j] = INF;
        for (j = up[i]; j <= M; ++ j) dp[i][j] = INF;
    }
    Count = K, Answer = INF;
    for (i = N; i >= 1; -- i)
    {
        for (j = down[i] + 1; j <= up[i] - 1; ++ j)
            if (dp[i][j] < INF) Answer = min (Answer, dp[i][j]);
        if (Answer != INF) break;
            if (up[i] <= M) -- Count;
    }
    if (Count == K) printf ("1\n%d\n", Answer);
    else printf ("0\n%d\n", Count);
    return 0;
}

int ZlycerQan = Main ();
int main (int argc, char *argv[]) {;}

 

以上是关于luogu P1941 飞扬的小鸟的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1941飞扬的小鸟——细节DP

洛谷 P1941飞扬的小鸟

P1941 飞扬的小鸟(背包)

P1941 飞扬的小鸟

P1941 飞扬的小鸟

P1941 飞扬的小鸟