PKU1038 Bugs Integrated, Inc. 状压DP
2016-03-07 21:54
369 查看
周伟的论文没能看懂感觉挺羞愧的然而现在我也没能理解。然后滚去看黑书,P138
首先我们先没枚举上一行的状态,dfs这一行的状态,用三进制来表示从上向下有连续的多少个0,然后我们就可以愉快地转移了。
虽然仅仅用时1266ms,但是我并没有明白为什么会这么快,原本以为会T的很惨的。
显然我们先枚举行,然后枚举上一行状态。此时极限数据会达到150*50000+*50000+,然后又5组数据……根本看不到希望
不过实际上会因为这一行很多不能放的和之前的限制把后面的50000+降低了非常多= =,感觉放到UOJ上绝对被hack狂魔折磨的不成人形
周伟的做法dfs同时枚举上一次的状态和这一次的状态,跑的会快很多,然而还没看懂= =
Problem: 1038 User: BPM136
Memory: 1160K Time: 1266MS
Language: G++ Result: Accepted
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 155
#define M 15
#define K 60000
int f[K][2];
bool map
[M];
int b[M],s[M];
int n,m,nm;
int x,y;
void init()
{
memset(map,0,sizeof(map));
memset(f,-1,sizeof(f));
}
void chu()
{
b[0]=1;
fo(i,1,10)b[i]=b[i-1]*3;
}
void dfs(int xu,int t,int k,int cnt,int num)
{
if(k>m)
{
f[cnt][xu&1]=max(f[cnt][xu&1],f[t][(xu-1)&1]+num);
return;
}
int tt=0;
if(map[xu][k])tt=2;
else if(s[k])tt=s[k]-1;else tt=0;
dfs(xu,t,k+1,cnt+tt*b[k-1],num);
if(k+1<=m&&s[k]==0&&s[k+1]==0&&!map[xu][k]&&!map[xu][k+1])
dfs(xu,t,k+2,cnt+2*b[k-1]+2*b[k],num+1);
if(k+2<=m&&s[k]<=1&&s[k+1]<=1&&s[k+2]<=1)
if(!map[xu][k]&&!map[xu][k+1]&&!map[xu][k+2])
dfs(xu,t,k+3,cnt+2*b[k-1]+2*b[k]+2*b[k+1],num+1);
}
int main()
{
chu();
int ttt=read();
while(ttt--)
{
init();
n=read(),m=read(),nm=read();
fo(i,1,nm)
{
x=read(),y=read();
map[x][y]=1;
}
f[b[m]-1][0]=0;
fo(i,1,n)
{
fo(j,0,b[m]-1)f[j][i&1]=-1;
fo(j,0,b[m]-1)
if(f[j][(i-1)&1]!=-1)
{
s[0]=1;
for(int t=j,k=1;k<=m;t/=3,k++)s[k]=t%3;
dfs(i,j,1,0,0);
}
}
int ans=-1;
fo(i,0,b[m]-1)ans=max(ans,f[i][n&1]);
printf("%d\n",ans);
}
return 0;
}
首先我们先没枚举上一行的状态,dfs这一行的状态,用三进制来表示从上向下有连续的多少个0,然后我们就可以愉快地转移了。
虽然仅仅用时1266ms,但是我并没有明白为什么会这么快,原本以为会T的很惨的。
显然我们先枚举行,然后枚举上一行状态。此时极限数据会达到150*50000+*50000+,然后又5组数据……根本看不到希望
不过实际上会因为这一行很多不能放的和之前的限制把后面的50000+降低了非常多= =,感觉放到UOJ上绝对被hack狂魔折磨的不成人形
周伟的做法dfs同时枚举上一次的状态和这一次的状态,跑的会快很多,然而还没看懂= =
Problem: 1038 User: BPM136
Memory: 1160K Time: 1266MS
Language: G++ Result: Accepted
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 155
#define M 15
#define K 60000
int f[K][2];
bool map
[M];
int b[M],s[M];
int n,m,nm;
int x,y;
void init()
{
memset(map,0,sizeof(map));
memset(f,-1,sizeof(f));
}
void chu()
{
b[0]=1;
fo(i,1,10)b[i]=b[i-1]*3;
}
void dfs(int xu,int t,int k,int cnt,int num)
{
if(k>m)
{
f[cnt][xu&1]=max(f[cnt][xu&1],f[t][(xu-1)&1]+num);
return;
}
int tt=0;
if(map[xu][k])tt=2;
else if(s[k])tt=s[k]-1;else tt=0;
dfs(xu,t,k+1,cnt+tt*b[k-1],num);
if(k+1<=m&&s[k]==0&&s[k+1]==0&&!map[xu][k]&&!map[xu][k+1])
dfs(xu,t,k+2,cnt+2*b[k-1]+2*b[k],num+1);
if(k+2<=m&&s[k]<=1&&s[k+1]<=1&&s[k+2]<=1)
if(!map[xu][k]&&!map[xu][k+1]&&!map[xu][k+2])
dfs(xu,t,k+3,cnt+2*b[k-1]+2*b[k]+2*b[k+1],num+1);
}
int main()
{
chu();
int ttt=read();
while(ttt--)
{
init();
n=read(),m=read(),nm=read();
fo(i,1,nm)
{
x=read(),y=read();
map[x][y]=1;
}
f[b[m]-1][0]=0;
fo(i,1,n)
{
fo(j,0,b[m]-1)f[j][i&1]=-1;
fo(j,0,b[m]-1)
if(f[j][(i-1)&1]!=-1)
{
s[0]=1;
for(int t=j,k=1;k<=m;t/=3,k++)s[k]=t%3;
dfs(i,j,1,0,0);
}
}
int ans=-1;
fo(i,0,b[m]-1)ans=max(ans,f[i][n&1]);
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- POJ 3254 - Corn Fields [状压DP]
- poj 2836
- poj 3254
- POJ 2441
- 2014 西安邀请赛状压DP
- Mega Man’s Missions
- 【2015新手赛网络赛】 1004 Good Subsets
- HDU 5561 【2015合肥现场赛】 Kingdom of Tree
- 关于AC自动机与DP的总结
- nyoj 合并游戏(状态压缩dp)
- HDU 5135 Little Zu Chongzhi's Triangles (2014年广州赛区现场赛I题)
- 【PA2014】【BZOJ3717】Pakowanie
- 【SCOI2007】【BZOJ1072】排列perm
- 【CERC2012】【BZOJ4057】Kingdoms
- 【SDOI2009】【BZOJ1879】Bill的挑战
- 【BZOJ2064】分裂
- Codevs2880 送外卖
- codeforces #302 Remembering Strings (dp)
- hdu 5418 Victor and World 状压DP
- 状压DP入门题集锦