洛谷1941飞扬的小鸟

题目:https://www.luogu.org/problemnew/show/P1941

dp。只是dp而已。作为自中午考试爆炸而阴郁的一下午一晚上中一点的慰藉。

滚动数组每次赋初值在这道题中变成了一种方便。处理障碍只需要将上一阶段对应位置赋成 INF 就行了。

注意降下来的那种情况得在完全背包运行完了之后再考虑。不然就可能同一阶段即下降又上升。

还有就是顶层可转移来的状态多些。全程都是不能触及到第0行的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const long long INF=0x7fffffff;
int n,m,k,x[10005],y[10005],uj[10005],dj[10005],p,h,l,cnt;
bool zh[10005];
long long d[2][1005],ans=INF;
void pan(int i)
{
    bool flag=0;
    for(int j=0;j<=m;j++)
        if(d[i%2][j]!=INF)
        {
            flag=1;break;
        }
    if(flag)return;
    printf("0\n%d",cnt);
    exit(0);
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<n;i++)scanf("%d%d",&x[i],&y[i]);
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d%d",&p,&l,&h);
        zh[p]=1;dj[p]=l;uj[p]=h;
    }
    for(int i=1;i<=n;i++)
    {
//        printf("i=%d\n",i);
        bool flag=0;
        for(int j=0;j<=m;j++)d[i%2][j]=INF;
        if(zh[i-1])
        {
            flag=1;
            for(int j=0;j<=dj[i-1];j++)d[(i-1)%2][j]=INF;
            for(int j=uj[i-1];j<=m;j++)d[(i-1)%2][j]=INF;
        }
        for(int j=x[i-1]+1;j<=m;j++)
        {
            d[i%2][j]=min(d[i%2][j],min(d[(i-1)%2][j-x[i-1]]+1,d[i%2][j-x[i-1]]+1));
//            printf("  d[%d]=%d\n",j,d[i%2][j]);
        }
        for(int j=m-x[i-1]+1;j<=m;j++)
        {
            d[i%2][m]=min(d[i%2][m],min(d[(i-1)%2][j]+1,d[i%2][j]+1));
//            printf("  d[%d]=%d\n",j,d[i%2][j]);
        }
        int ll=m-y[i-1];
        for(int j=1;j<=ll;j++)
        {
            d[i%2][j]=min(d[i%2][j],d[(i-1)%2][j+y[i-1]]);
//            printf("  d[%d]=%d\n",j,d[i%2][j]);
        }
        pan(i);
        if(flag)cnt++;
    }
    for(int i=1;i<=m;i++)
        ans=min(ans,d[n%2][i]);
    printf("1\n%lld",ans);
    return 0;    
}

 

posted on 2018-02-27 20:18  Narh  阅读(85)  评论(0编辑  收藏

导航