poj 2430 Lazy Cows 状压dp

这个题目还是比较容易想到用状态dp来解的,但是状态的转移比较麻烦,并且加上有离散化,比较容易出错。

dp[i][j][k]表示覆盖前i列,用了j个矩形,当前覆盖状态为k的最优解。

k==1:覆盖1号格子

k==2:覆盖2号格子

k==3:覆盖1,2号格子,并且为同一个矩形

k==4:覆盖1,2号格子,并且为不同矩形

那么转移的时候就需要考虑,新建矩形,或者直接把当前矩形边长延伸。转移种类较多。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e3+9;
bool a[3][maxn];
int x[maxn],y[maxn],f[maxn],g[maxn];
int dp[maxn][maxn][5];
struct D
{
    int id,key;
    bool operator <(const D & xx) const
    {
        return key<xx.key;
    }
}h[maxn];
int main()
{
//    freopen("in.txt","r",stdin);
    int n,K,b;
    while(scanf("%d %d %d",&n,&K,&b)!=EOF)
    {
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&x[i],&y[i]);
            h[i].key=y[i],h[i].id=i;
        }
        sort(h+1,h+1+n);
        int top=0;
        f[h[1].id]=++top;
        g[top]=h[1].key;
        for(int i=2;i<=n;i++)
        {
            if(h[i].key!=h[i-1].key) ++top;
            f[h[i].id]=top;
            g[top]=h[i].key;
        }
        for(int i=1;i<=n;i++)
        a[x[i]][f[i]]=1;

        memset(dp,50,sizeof(dp));
        dp[0][0][0]=0;
        for(int k=0;k<top;k++)
        {
            for(int i=0;i<=K;i++)
            for(int j=0;j<5;j++)
            {
                if(a[1][k+1]==0)
                dp[k+1][i+1][2]=min(dp[k+1][i+1][2],dp[k][i][j]+1);

                if(a[2][k+1]==0)
                dp[k+1][i+1][1]=min(dp[k+1][i+1][1],dp[k][i][j]+1);

                dp[k+1][i+1][3]=min(dp[k+1][i+1][3],dp[k][i][j]+2);
                dp[k+1][i+2][4]=min(dp[k+1][i+2][4],dp[k][i][j]+2);

                if(j==1)
                {
                    if(a[2][k+1]==0)
                    dp[k+1][i][j]=min(dp[k+1][i][j],dp[k][i][j]+g[k+1]-g[k]);
                    else
                    dp[k+1][i+1][4]=min(dp[k+1][i+1][4],dp[k][i][j]+g[k+1]-g[k]+1);
                }
                else if(j==2)
                {
                    if(a[1][k+1]==0)
                    dp[k+1][i][j]=min(dp[k+1][i][j],dp[k][i][j]+g[k+1]-g[k]);
                    else
                    dp[k+1][i+1][4]=min(dp[k+1][i+1][4],dp[k][i][j]+g[k+1]-g[k]+1);
                }
                else if(j==3)
                {
                    dp[k+1][i][j]=min(dp[k+1][i][j],dp[k][i][j]+(g[k+1]-g[k])*2);
                }
                else if(j==4)
                {
                    dp[k+1][i][j]=min(dp[k+1][i][j],dp[k][i][j]+(g[k+1]-g[k])*2);

                    if(a[2][k+1]==0)
                    dp[k+1][i][1]=min(dp[k+1][i][1],dp[k][i][j]+g[k+1]-g[k]);
                    else
                    dp[k+1][i+1][4]=min(dp[k+1][i+1][4],dp[k][i][j]+g[k+1]-g[k]+1);

                    if(a[1][k+1]==0)
                    dp[k+1][i][2]=min(dp[k+1][i][2],dp[k][i][j]+g[k+1]-g[k]);
                    else
                    dp[k+1][i+1][4]=min(dp[k+1][i+1][4],dp[k][i][j]+g[k+1]-g[k]+1);
                }
            }
        }

        int ans=1e9;

        for(int k=0;k<=K;k++)
        for(int i=0;i<5;i++)
        ans=min(ans,dp[top][k][i]+K-k);
        cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(poj 2430 Lazy Cows 状压dp)