您的位置:首页 > 其它

Pebbles 状态压缩&&dp 状态转移

2013-11-10 09:15 375 查看
[align=left]Problem Description[/align]
You're given an unlimited number of pebbles to distribute across an N x N game board (N drawn from [3, 15]), where each square on the board contains some positive point value between 10 and 99, inclusive. A 6 x 6 board might look like this:

/*
状态压缩,dp,
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
int dp[20][1601];
int s[25],state[1601],S,n;
int d[20][20];
vector<int>G[1601];
int legal(int x)//判断状态是否合法
{
int it;
for(it=1;it<15;it++)
{
if((x&s[it])&&(x&s[it-1]))return false;

}
return true;
}
void get_state()//存储一行时的合法状态
{
int st;
S=0;
for(st=0;st<=15;st++) s[st]=(1<<st);
for(st=0;st<(1<<15);st++)
{
if(legal(st))
{
++S;
state[S]=st;
}
}
}
int link(int u,int v)//两个状态相邻时是否合适
{
int kt;
if((u&s[0])&&((v&s[1])||v&s[0]))return false;
if((u&s[14])&&((v&s[14])||(v&s[13])))return false;
for(kt=1;kt<14;kt++)
{
if((u&s[kt])&&((v&s[kt])||(v&s[kt-1])||(v&s[kt+1]))) return false;
}
return true;
}
void  fuhe()//找合适的相邻状态
{
int it,jt;
for(it=1;it<=S;it++)
G[it].clear();
for(it=1;it<=S;it++)
for(jt=1;jt<=S;jt++)
{
if(link(state[it],state[jt]))
G[it].push_back(jt);
}
}
int sum(int low,int sta)//对每一种状态计算相应的和
{
int ans=0,it;
if(sta>=s
)return 0;
for(it=0;it<n;it++)
if(sta&s[it])ans+=d[low][it];
return ans;
}
int main()
{
char str[1001],ch;
get_state();
fuhe();
while(gets(str))
{
int i,j,k;
n=(strlen(str)+1)/3;//判断出行列
for(i=0;i<n;i++)
{
d[0][i]=(str[3*i]-'0')*10+(str[i*3+1]-'0');
}
for(i=1;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&d[i][j]);
ch=getchar();
ch=getchar();
memset(dp,0,sizeof(dp));
for(i=1;i<=S;i++)
{
if(state[i]>=s
)break;
dp[0][i]=sum(0,state[i]);//赋初值,以便以下的状态转移
}
for(i=1;i<n;i++)
for(j=1;j<=S;j++)
{
if(state[j]>s
)break;
int temp=sum(i,state[j]);
for(k=0;k<G[j].size();k++)
if(dp[i][j]<dp[i-1][G[j][k]])//状态转移
dp[i][j]=dp[i-1][G[j][k]];
dp[i][j]+=temp;
}
int maxn=0;
for(i=1;i<=S;i++)//再次遍历
if(dp[n-1][i]>maxn)
maxn=dp[n-1][i];
printf("%d\n",maxn);

}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: