您的位置:首页 > 其它

POJ--2441--Arrange the Bulls--状压DP-滚动数组优化

2013-08-12 10:43 381 查看
dp[i][j] 表示前 i 头牛放成 j 状态的数量

然后就可以状压DP 了,提前看了一discuss,说要用滚动数组,想想也是,加上数组优化后空间用了9M,不用滚动数组的话使用空间就是 9*10 = 90M ,题目只给了64M的空间。刚提交了一下不优化空间的,还真MLE了。。。。。。。。。我是不是很无聊。。。亲自验证一下而已-_-#

如果不想加滚动数组优化的话,把DP数组开到dp[21][50W] 也是可以过的,40多M的空间 -_-$

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 20;
int dp[2][1<<MAXN];
int sc[2][1<<MAXN];
int nsc[2];
int n,m;
int p[MAXN+10][MAXN+10];
int np[MAXN];

void init()
{
memset(dp,0,sizeof(dp));
memset(nsc,0,sizeof(nsc));
memset(np,0,sizeof(np));
for(int i=1;i<=n;i++)
{
scanf("%d",np+i);
for(int j=0;j<np[i];j++)
{
scanf("%d",p[i]+j);
}
}
}

void solve()
{
init();
dp[0][0]=1;
sc[0][nsc[0]++]=0;
int sta;
for(int line=1;line<=n;line++)
{
for(int i=0;i<nsc[0];i++)
{
sta=sc[0][i];
for(int k=0;k<np[line];k++)
{
int pos=1<<p[line][k];
if((sta&pos)==0)
{
if(dp[1][(sta|pos)]==0)
{
sc[1][nsc[1]++]=sta|pos;
}
dp[1][sta|pos]+=dp[0][sta];
}
}
}
for(int i=0;i<nsc[1];i++)
{
dp[0][sc[1][i]]=dp[1][sc[1][i]];
sc[0][i]=sc[1][i];
}
nsc[0]=nsc[1];nsc[1]=0;
memset(dp[1],0,sizeof(dp[1]));
}
int ans=0;
for(int i=0;i<nsc[0];i++)
{
ans+=dp[0][sc[0][i]];
}
printf("%d\n",ans);
}

int main()
{
freopen("atb.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
solve();
}
return 0;
}


这个代码是不加滚动数组优化的, 比较直观一点,但是数组不要傻乎乎的开满100W,50W就够了,也是过了滴
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 20;
const int MAXF = 500000;
int dp[21][MAXF];
int sc[21][MAXF];
int nsc[21];
int n,m;
int p[MAXN+10][MAXN+10];
int np[MAXN];

void init()
{
memset(dp,0,sizeof(dp));
memset(nsc,0,sizeof(nsc));
memset(np,0,sizeof(np));
for(int i=1;i<=n;i++)
{
scanf("%d",np+i);
for(int j=0;j<np[i];j++)
{
scanf("%d",p[i]+j);
}
}
}

void solve()
{
init();
dp[0][0]=1;
sc[0][nsc[0]++]=0;
int sta;
for(int line=1;line<=n;line++)
{
for(int i=0;i<nsc[line-1];i++)
{
sta=sc[line-1][i];
for(int k=0;k<np[line];k++)
{
int pos=1<<p[line][k];
if((sta&pos)==0)
{
if(dp[line][(sta|pos)]==0)
{
sc[line][nsc[line]++]=sta|pos;
}
dp[line][sta|pos]+=dp[line-1][sta];
}
}
}
/*
for(int i=0;i<nsc[1];i++)
{
dp[0][sc[1][i]]=dp[1][sc[1][i]];
sc[0][i]=sc[1][i];
}
nsc[0]=nsc[1];nsc[1]=0;
memset(dp[1],0,sizeof(dp[1]));
*/
}
int ans=0;
for(int i=0;i<nsc
;i++)
{
ans+=dp
[sc
[i]];
}
printf("%d\n",ans);
}

int main()
{
freopen("atb.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: