洛谷P1941飞扬的小鸟 完全背包

思维难度不大,就是有许多细节要注意。
1.不能开滚动数组。
2.要特判飞过天花板的情况。
Code:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxm = 1009;
const int maxn = 10000 + 4;
const int inf  = 10000000 + 4;
int F[maxn][maxm], up[maxn], down[maxn], height[maxn];
int pipeup[maxn], pipedown[maxn], n,m,k, ans;
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d%d",&n,&m,&k);
    for(int i = 0;i < n;++i)
    {
        scanf("%d%d",&up[i],&down[i]);
        height[i + 1] = m + up[i];
    }
    for(int i = 1;i <= k;++i)
    {
        int x;
        scanf("%d",&x);
        scanf("%d%d",&pipedown[x],&pipeup[x]);
    }
    height[0] = m;
    F[0][0] = inf;
    for(int i = 1;i <= n;++i)
    {
        for(int j = 1;j <= height[i]; ++j)F[i][j] = inf;
        for(int j = 1;j <= height[i]; ++j)if(j - up[i-1] > 0)F[i][j] = min(F[i][j],F[i-1][j-up[i-1]] + 1);
        for(int j = 1;j <= height[i]; ++j)if(j - up[i-1] > 0) F[i][j] = min(F[i][j], F[i][j-up[i-1]] + 1);
        for(int j = 1;j <= m - down[i-1]; ++j)F[i][j] = min(F[i][j], F[i-1][j + down[i-1]]);
        for(int j = m + 1;j <= height[i];++j)F[i][m] = min(F[i][m], F[i][j]);
        for(int j = 1;j <= height[i]; ++j)
        {
            if(pipeup[i])
            {
                if(j >= pipeup[i] || j <= pipedown[i]) F[i][j] = inf;
            }
            if(F[i][j] < inf) ans = i;
        }
    }
    if( ans == n)
    {
        printf("1
");
        int minv = inf;
        for(int i = 1;i <= height[n]; ++i)
        {
            minv = min(minv,F[n][i]);
        }
        printf("%d",minv);
    }
    else{
        printf("%d
",0);
        int cnt = 0;
        for(int i = 1;i <= ans;++i)if(pipeup[i]) ++cnt;
        printf("%d",cnt);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/guangheli/p/9845196.html