poj 1185 状态DP

来源:互联网 发布:如何查询服务器端口 编辑:程序博客网 时间:2024/06/05 22:43

经典的状态DP啊,虽然也可以用最大点独立集来做。不严谨的话,这应该是我第一道状态DP题。

刚开始没有思路,不知道怎么设状态。看了网上一些思路,有点头绪了。

分析:对于第k行哪些点放炮兵使得1~k行炮兵数最多与第k-1,k-2行哪些点放炮兵有关,所以对于第k行需要前面两行的(k-1,k-2)的状态才能确定,

每个位置状态只有放与不放(0,1),所以想到用状态压缩dp[k][a][b]来表示,a表示第k行放炮兵的第a种状态,b表示第k-1行放炮兵的第b种状态。

为什么这样设状态?因为这样就可以进行状态转移了,如果设dp[k][a],则发现无法进行状态转移,此时常见的方法就是增加维度,即增加新的因素,更细致的描述状态。

dp[k][a][b]=max(dp[k][a][b],dp[k-1][b][p]+num[a]); 约束条件是 sta[a]&sta[b]==0, sta[a]&sta[p]==0(即k的第a种状态与k-1的第b种状态,k-2的第p种状态都不冲突。)

其中sta[a]是第k行所对应的第a个状态,num[a]为第a个状态对应的可以放炮兵的位置个数。

其他一些要说明的细节或者求法,在代码里。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAX 1<<7int N,M,ans;int dp[111][MAX][MAX];int sta[MAX],num[MAX],sum,presta[MAX],prenum,prepresta[MAX],preprenum;char ch[111][15];void dfs(int i,int j,int p,int s){    if(j>=M) {sta[++sum]=p;num[sum]=s;return ;}    if(ch[i][j]=='P') dfs(i,j+3,p|(1<<j),s+1);    dfs(i,j+1,p,s);}void DP(){    int i,j,k,p;    prenum=preprenum=1;    for(k=1;k<=N;k++)    {        sum=0;  //第k行对应的状态数。(即 有几个状态)        memset(num,0,sizeof(num));  //用来存放 每个状态中1的个数(即可以放炮兵的位置数)        dfs(k,0,0,0);    //求第k行对应的状态,以及每个状态可以放炮兵的个数。        for(i=1;i<=sum;i++)        {            for(j=1;j<=prenum;j++)            {                for(p=1;p<=preprenum;p++)                {                    if(sta[i]&presta[j]) continue;                    if(sta[i]&prepresta[p]) continue;                    dp[k][i][j]=max(dp[k][i][j],dp[k-1][j][p]+num[i]);                }            }        }        for(i=1;i<=prenum;i++)   //把上一行给上上行        {            prepresta[i]=presta[i];        }        preprenum=prenum;        for(i=1;i<=sum;i++)   //把当前行给上一行        {            presta[i]=sta[i];        }        prenum=sum;    }    ans=0;    for(i=1;i<=sum;i++)        for(j=1;j<=prenum;j++)    {        ans=max(ans,dp[N][i][j]);    }}int main(){    int i,j;    scanf("%d%d",&N,&M);    getchar();    for(i=1;i<=N;i++)    {        gets(ch[i]);    }    DP();    printf("%d\n",ans);    return 0;}


 

 

0 0
原创粉丝点击