POJ 2430 状压DP

来源:互联网 发布:叶利钦与普京 知乎 编辑:程序博客网 时间:2024/06/07 16:45

题意:
这里写图片描述
这里写图片描述
思路:
先预处理出所有格子的statement
statement=1–>只有上边的格子被覆盖
statement=2–>只有下边的格子被覆盖
statement=3–>上下都被覆盖

f[i][j][k]表示状态为i时,前j个地方的奶牛,盖k座房子 最少盖住的格子

i有四种情况

  • i=1代表只有上边的格子被覆盖
  • i=2代表只有下边的格子被覆盖
  • i=3代表上下被同一个房子覆盖
  • i=4代表上下被不同房子覆盖

    状态转移很麻烦 特别麻烦

  • statement=1时

f[1][j][k]=min(min(f[1][j-1][k-1],min(f[2][j-1][k-1],min(f[3][j-1][k-1],f[4][j-1][k-1])))+1,f[1][j-1][k]+node[j].pos-node[j-1].pos);
f[1][j][k]=min(f[1][j][k],f[4][j-1][k]+node[j].pos-node[j-1].pos);
f[3][j][k]=min(temp+2,f[3][j-1][k]+2*(node[j].pos-node[j-1].pos));
f[4][j][k]=f[4][j-1][k]+2*(node[j].pos-node[j-1].pos);
f[4][j][k]=min(f[4][j][k],f[1][j-1][k-1]+node[j].pos-node[j-1].pos+1);
f[4][j][k]=min(f[4][j][k],f[2][j-1][k-1]+node[j].pos-node[j-1].pos+1);

  • statement=2时同理
  • statement=3时

int temp=min(f[1][j-1][k-1],min(f[2][j-1][k-1],min(f[3][j-1][k-1],f[4][j-1][k-1])));
f[3][j][k]=min(temp+2,f[3][j-1][k]+2*(node[j].pos-node[j-1].pos));
if(k>1)f[4][j][k]=min(f[1][j-1][k-2],min(f[2][j-1][k-2],min(f[3][j-1][k-2],f[4][j-1][k-2])))+2;
f[4][j][k]=min(f[4][j][k],f[4][j-1][k]+2*(node[j].pos-node[j-1].pos));
f[4][j][k]=min(f[4][j][k],f[1][j-1][k-1]+node[j].pos-node[j-1].pos+1);
f[4][j][k]=min(f[4][j][k],f[2][j-1][k-1]+node[j].pos-node[j-1].pos+1);

最后代码如下:

//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n,K,b,cnt,f[5][1005][1005];struct Node{int sta,pos;}node[1005];bool cmp(Node a,Node b){    return a.pos<b.pos;}int main(){    scanf("%d%d%d",&n,&K,&b);    for(int i=1;i<=n;i++)        scanf("%d%d",&node[i].sta,&node[i].pos);    sort(node+1,node+1+n,cmp);    for(int i=1;i<=n;i++){        if(node[i].pos==node[i-1].pos)            node[cnt].sta=3;        else node[++cnt]=node[i];    }    node[0].pos=node[1].pos;    memset(f,0x3f,sizeof(f));    f[1][0][1]=f[2][0][1]=1,f[3][0][1]=f[4][0][2]=2;    for(int i=1;i<=4;i++){        for(int j=1;j<=cnt;j++){            for(int k=K;k;k--){                if(node[j].sta==1){                    int temp=min(f[1][j-1][k-1],min(f[2][j-1][k-1],min(f[3][j-1][k-1],f[4][j-1][k-1])));                    f[1][j][k]=min(temp+1,f[1][j-1][k]+node[j].pos-node[j-1].pos);                    f[1][j][k]=min(f[1][j][k],f[4][j-1][k]+node[j].pos-node[j-1].pos);                    f[3][j][k]=min(temp+2,f[3][j-1][k]+2*(node[j].pos-node[j-1].pos));                    f[4][j][k]=f[4][j-1][k]+2*(node[j].pos-node[j-1].pos);                    f[4][j][k]=min(f[4][j][k],f[1][j-1][k-1]+node[j].pos-node[j-1].pos+1);                    f[4][j][k]=min(f[4][j][k],f[2][j-1][k-1]+node[j].pos-node[j-1].pos+1);                }                else if(node[j].sta==2){                    int temp=min(f[1][j-1][k-1],min(f[2][j-1][k-1],min(f[3][j-1][k-1],f[4][j-1][k-1])));                    f[2][j][k]=min(temp+1,f[2][j-1][k]+node[j].pos-node[j-1].pos);                    f[2][j][k]=min(f[2][j][k],f[4][j-1][k]+node[j].pos-node[j-1].pos);                    f[3][j][k]=min(temp+2,f[3][j-1][k]+2*(node[j].pos-node[j-1].pos));                    f[4][j][k]=f[4][j-1][k]+2*(node[j].pos-node[j-1].pos);                    f[4][j][k]=min(f[4][j][k],f[1][j-1][k-1]+node[j].pos-node[j-1].pos+1);                    f[4][j][k]=min(f[4][j][k],f[2][j-1][k-1]+node[j].pos-node[j-1].pos+1);                }                else{                    int temp=min(f[1][j-1][k-1],min(f[2][j-1][k-1],min(f[3][j-1][k-1],f[4][j-1][k-1])));                    f[3][j][k]=min(temp+2,f[3][j-1][k]+2*(node[j].pos-node[j-1].pos));                    if(k>1)f[4][j][k]=min(f[1][j-1][k-2],min(f[2][j-1][k-2],min(f[3][j-1][k-2],f[4][j-1][k-2])))+2;                    f[4][j][k]=min(f[4][j][k],f[4][j-1][k]+2*(node[j].pos-node[j-1].pos));                    f[4][j][k]=min(f[4][j][k],f[1][j-1][k-1]+node[j].pos-node[j-1].pos+1);                    f[4][j][k]=min(f[4][j][k],f[2][j-1][k-1]+node[j].pos-node[j-1].pos+1);                }            }        }    }    for(int i=1;i<=4;i++)f[1][cnt][K]=min(f[1][cnt][K],f[i][cnt][K]);    printf("%d\n",f[1][cnt][K]);}

这里写图片描述

0 0
原创粉丝点击