概述
由于一个炮能影响的范围最多到下两行...所以两行两行来DP..而两行的情况直接搜出来..由于n可能是奇数..为了处理方便..n为奇数时..加一行全0的..把n变为偶数...
数据太弱..自己出了个100*10的全1输入来跑...N久才出来..真正完美的解法还是应该用状态压缩DP...
Program:
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
#include<set>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#define ll long long
#define oo 1000000007
using namespace std;
struct node
{
int h[33][2],num;
}a[4005],p;
int n,m,anum,pre[2][4005],prenum;
int arc[105][12];
int dp[2][4005],ans;
void dfs(int y,int x)
{
int i,j;
for (i=1;i<=p.num;i++)
if (abs(y-p.h[i][0])+abs(x-p.h[i][1])==2) return;
p.num++;
p.h[p.num][0]=y; p.h[p.num][1]=x;
a[++anum]=p;
for (j=x+1;j<=m;j++) dfs(y,j);
for (i=y+1;i<=2;i++)
for (j=1;j<=m;j++)
dfs(i,j);
p.num--;
return;
}
void prework()
{
int i,j;
anum=0;
p.num=0;
a[++anum]=p;
for (i=1;i<=2;i++)
for (j=1;j<=m;j++)
dfs(i,j);
return;
}
bool ok(int p,int t) // 判断当前状态适合当前图否
{
int i;
for (i=1;i<=a[p].num;i++)
if (arc[t+a[p].h[i][0]-1][a[p].h[i][1]]==0) return false;
return true;
}
bool f(int p1,int p2) // 判断状态间冲突否
{
int i,j;
for (i=1;i<=a[p1].num;i++)
for (j=1;j<=a[p2].num;j++)
if (abs(a[p1].h[i][0]-a[p2].h[j][0]-2)+abs(a[p1].h[i][1]-a[p2].h[j][1])==2) return false;
return true;
}
int main()
{
int i,jj,j,t,k,mm;
while (~scanf("%d%d",&n,&m))
{
prework();
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
scanf("%d",&arc[i][j]);
if (n%2)
{
n++;
for (j=1;j<=m;j++) arc[n][j]=0;
}
mm=k=0;
for (i=1;i<=anum;i++)
if (ok(i,1))
{
dp[k][i]=a[i].num;
pre[k][++mm]=i;
}
prenum=mm;
for (t=3;t<=n;t+=2)
{
k=1-k;
memset(dp[k],0,sizeof(dp[k]));
mm=0;
for (i=1;i<=anum;i++)
if (ok(i,t))
{
pre[k][++mm]=i;
for (jj=1;jj<=prenum;jj++)
{
j=pre[1-k][jj];
if (dp[k][i]<dp[1-k][j]+a[i].num && f(j,i))
dp[k][i]=dp[1-k][j]+a[i].num;
}
}
prenum=mm;
}
ans=0;
for (i=1;i<=anum;i++)
if (dp[k][i]>ans) ans=dp[k][i];
printf("%dn",ans);
}
return 0;
}
最后
以上就是无情烧鹅为你收集整理的HDOJ - 4559 排兵布阵 DP的全部内容,希望文章能够帮你解决HDOJ - 4559 排兵布阵 DP所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复