首页 > 其他 > 详细

luogu P1941 飞扬的小鸟

时间:2017-08-22 22:39:56      阅读:256      评论:0      收藏:0      [点我收藏+]

二次联通门 : 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 飞扬的小鸟

原文:http://www.cnblogs.com/ZlycerQan/p/7413830.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!