您的位置:首页 > 其它

sgu 132 Another Chocolate Maniac

2016-03-11 22:55 274 查看
装压好题!

首先我们要从两个相邻的格子不能同时为空入手,然后我们不妨枚举每一行最后的状态,那下一行怎么办,我们还需要用一维来记录这一行的进位,也就是这一行用竖的格子放后的状态然后直接枚举即可,看起来像70*(3^14)的复杂度,其实我们对最终状态可以预处理,可以发现最多不超过21个,所以结论是dp[x][f]=dp[y][w]+count[f]+vis[x^f^s^w];

其中count数组记录的是当前二进制位数,vis记录横着放需要多少个,至于s是当前行candle的状态。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define mp(a,b) make_pair(a,b)
#define xx first
#define yy second
using namespace std;
typedef long long LL;
const int inf=1000000000;
int dp[2][128][128],dp1[128][128];
char c[105][105];
int vis[128];
int cc[128];
vector<int>g;
vector<int>g1[128];
int main()
{
int i,j,u,n,m;
cin>>n>>m;
for(i=1;i<=n;i++){ scanf("%s",c[i]);
for(j=m;j>=1;j--) c[i][j]=c[i][j-1];
}
u=0;
int p=1<<m;
for(i=0;i<p;i++){
vis[i]=inf;
}
for(i=1;i<p;i++){
cc[i]=cc[i^(i^(i&(i-1)))]+1;
}
vis[0]=0;
for(i=1;i<p;i++){
int w=i&(i-1);
w=i^w;
if((i&(w<<1))==0) continue;
vis[i]=vis[i^w^(w<<1)]+1;
}
for(i=0;i<p;i++){
for(j=0;j<p;j++){
if((i|j)==i){
g1[i].push_back(j);
}
}
}
for(j=0;j<p;j++){
int q=(p-1)^j;
int w=((p-1)^j)<<1;
if((q&w)!=0) continue;
g.push_back(j);
}
for(i=0;i<p;i++){
for(j=0;j<p;j++){
dp[u][i][j]=1000000000;
}
}
dp[u][p-1][0]=0;
for(i=1;i<=n;i++){
u=u^1;
int s=0;
for(j=m;j>=1;j--){
s=s<<1;
if(c[i][j]=='*'){
s+=1;
}
}
for(j=0;j<p;j++){
int q=g1[j].size();
for(int f=0;f<q;f++){
dp1[j][g1[j][f]]=inf;
}
}
int q=g.size();
for (j=0;j<q;j++) {
int v=g[j];
int w=g1[v].size();
for(int f=0;f<w;f++){
if(dp[u^1][v][g1[v][f]]!=inf&&(g1[v][f]&s)==0){
for(int y1=0;y1<q;y1++){
int x=g[y1];
if((x|(g1[v][f]|s))!=x) continue;
if((((p-1)^v)&((p-1)^x))!=0) continue;
int p1=x^((g1[v][f]|s));
int ww=g1[p1].size();
for(int y=0;y<ww;y++){
dp1[x][g1[p1][y]]=min(dp1[x][g1[p1][y]],dp[u^1][v][g1[v][f]]+vis[p1^g1[p1][y]]+cc[g1[p1][y]]);
}
}
}
}
}
for(j=0;j<p;j++){
int q=g1[j].size();
for(int f=0;f<q;f++){
dp[u][j][g1[j][f]]=dp1[j][g1[j][f]];
}
}
}
p=g.size();
int s=inf;
for(i=0;i<p;i++){
s=min(s,dp[u][g[i]][0]);
}
cout<<s<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: