当前位置:编程学习 > C/C++ >>

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;  
}  

 


补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,