您的位置:首页 > 其它

poj 1185 状态压缩dp

2015-11-29 22:52 399 查看
题目链接:http://poj.org/problem?id=1185

第i行的状态由第I-1行和第i-2行决定

dp[i][j][k] = max(dp[i][j][k],dp[i-1][k][p]+cou[j]);

初始化第i=0行就够了,因为不会访问i-2

#include <cstdio>//改成c++就过原来用c的,wal
<span style="font-family: Arial, Helvetica, sans-serif;">#include <cstring></span>
int n,m;
int sta[60],cou[100]; //60是因为满足题目条件的,即相隔2个单位的,同时小于1<<10的,刚好只有60个,可以自己打打看,
int dp[110][60][60];
int map[110];
char str[12];

int max(int a,int b)
{
if(a > b)
return a;
return b;
}

int main()
{
int i,j,k,p;
int sp,tmp;

while(~scanf("%d %d",&n,&m))
{
memset(map,0,sizeof(map));
memset(dp,-1,sizeof(dp));
memset(cou,0,sizeof(cou));

for(i = 0; i < n; i++)
{
scanf("%s",str);
for(j = 0; j < m; j++)
{
if(str[j] == 'H')
map[i]+=(1<<j);
}
}

sp = 0;
tmp = (1<<m);
for(i = 0; i < tmp; i++)
{
if(!(i&(i<<2)) && !(i&(i<<1)))
{
p = i;
while(p)
{
cou[sp]++;
p&=(p-1);
}
sta[sp++] = i;
}
}

for(i = 0; i < sp; i++)
{
if(!(map[0]&sta[i]))
{
dp[0][i][0] = cou[i];
}
}

for(i = 1; i < n; i++)
{
for(j = 0; j < sp; j++)
{
if(!(map[i]&sta[j]))
{
for(k = 0; k < sp; k++)
{
if(!(map[i-1]&sta[k]) && !(sta[j]&sta[k]))
{
for(p = 0; p < sp; p++)
{
if(!(sta[p]&sta[j]) && !(sta[p]&sta[k]) && dp[i-1][k][p]!=-1)
{
dp[i][j][k] = max(dp[i][j][k],dp[i-1][k][p]+cou[j]);
}
}
}
}
}
}
}
tmp = 0;
for(i = 0; i < n; i++)
{
for(j = 0; j < sp; j++)
{
for(k = 0; k < sp; k++)
{
tmp = max(tmp,dp[i][j][k]);
}
}
}
printf("%d\n",tmp);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: