题目链接:Pebbles

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1504    Accepted Submission(s): 865

Problem Description
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:

The player distributes pebbles across the board so that:

?At most one pebble resides in any given square.
?No two pebbles are placed on adjacent squares. Two squares are considered adjacent if they are horizontal, vertical, or even diagonal neighbors. There's no board wrap, so 44 and 61 of row three aren't neighbors. Neither are 33 and 75 nor 55 and 92.

The goal is to maximize the number of points claimed by your placement of pebbles.

Write a program that reads in a sequence of boards from an input file and prints to stdout the maximum number of points attainable by an optimal pebble placement for each.

 
Input
Each board is expressed as a series of lines, where each line is a space-delimited series of numbers. A blank line marks the end of each board (including the last one)

 
Output
then your program would print the maximum number of points one can get by optimally distributing pebbles while respecting the two rules, which would be this (each output should be printed on a single line and followed with a newline):

 题解:代码虽然长,却是我调了四个小时调出来的。QAQ
二进制表示每一行的状态,初始化记录一整行每一个状态的值,用cnt[i][j]表示,j表示这一行的状态。然后dp开始转移,对于第 i 行,枚举每一个状态j,对于状态j,首先分析j是否满足相邻的最多有一个石子,然后考虑 i-1 位,分析i-1可能的状态,dfs一下寻找i-1行的最大值maxx,所以dp[i][j]  = maxx + cnt[i][j].
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[][<<];
int cnt[][<<];
int a[][],n;
char s[];
int vis[];
int maxx = ;
void dfs(int i,int now,int state,int sumstate)
{
maxx = max(maxx,dp[i][sumstate]);
if(vis[now]==)
{
if(now<n-)
{
dfs(i,now+,,sumstate);
}
else
{
return;
}
}
else if(vis[now]==)
{
if(now>=n-&&state==) dfs(i,now+,,sumstate+(<<now));
else if(now>=n-&&state==) return ;
else if(now<n-&&state==)
{
dfs(i,now+,,sumstate+(<<now));
dfs(i,now+,,sumstate);
}
else if(now<n-&&state==)
{
dfs(i,now+,,sumstate);
}
}
return;
}
int cal(int c1,int c2)
{
return ((c1-'')*+c2-'');
}
bool judge(int state) //判断此状态是否符合
{
for(int i=;i<n-;i++)
{
if(((<<i)&state)>&&((<<(i+))&state)>) return ;
}
return ;
}
int main()
{
while(gets(s))
{
int len = strlen(s);
n = (len+)/;
int ans = ;
for(int i=;i<len;i+=)
{
a[][ans++] = cal(s[i],s[i+]);
}
for(int i=;i<n;i++)
{
for(int j=;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int i=;i<n;i++) //预处理记录cnt[i][j]
{
for(int j=;j<(<<(n));j++)
{
int sum = ;
for(int k=;k<n;k++)
{
if(((<<k)&j)>)
{
sum += a[i][k];
}
}
cnt[i][j] = sum;
}
}
for(int j=;j<(<<n);j++) dp[][j] = cnt[][j];
for(int i=;i<n;i++) //枚举每一行,枚举每个状态,判断可行性。
{
for(int j=;j<(<<n);j++)
{
if(!judge(j)) continue;
memset(vis,,sizeof(vis));
for(int k=;k<n;k++)
{
if(k==)
{
if(((<<k)&j)==&&((<<(k+))&j)==)
{
vis[k] = ;
}
}
else if(k==n-)
{
if(((<<k)&j)==&&((<<(k-))&j)==)
{
vis[k] = ;
}
}
else
{
if(((<<k)&j)==&&((<<(k-))&j)==&&((<<(k+))&j)==)
{
vis[k] = ;
}
}
}
maxx = ; //dfs寻找i-1行的最大值
if(vis[]==)
dfs(i-,,,);
else
{
dfs(i-,,,);
dfs(i-,,,);
}
dp[i][j] = maxx+cnt[i][j];
}
}
getchar();
gets(s);
int maxn = ;
for(int i=;i<(<<n);i++) maxn = max(maxn,dp[n-][i]);
printf("%d\n",maxn);
memset(dp,,sizeof(dp));
}
return ;
}
/*
10 20 30
10 20 30
10 20 30
*/
 
 

HDU 2167 Pebbles(状压DP)的更多相关文章

  1. HDU 4284Travel(状压DP)

    HDU 4284    Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...

  2. HDU 4336 容斥原理 || 状压DP

    状压DP :F(S)=Sum*F(S)+p(x1)*F(S^(1<<x1))+p(x2)*F(S^(1<<x2))...+1; F(S)表示取状态为S的牌的期望次数,Sum表示 ...

  3. HDU 3001 Travelling ——状压DP

    [题目分析] 赤裸裸的状压DP. 每个点可以经过两次,问经过所有点的最短路径. 然后写了一发四进制(真是好写) 然后就MLE了. 懒得写hash了. 改成三进制,顺利A掉,时间垫底. [代码] #in ...

  4. HDU - 5117 Fluorescent(状压dp+思维)

    原题链接 题意 有N个灯和M个开关,每个开关控制着一些灯,如果按下某个开关,就会让对应的灯切换状态:问在每个开关按下与否的一共2^m情况下,每种状态下亮灯的个数的立方的和. 思路1.首先注意到N< ...

  5. hdu 4114(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4114 思路:首先是floyd预处理出任意两点之间的最短距离.dp[state1][state2][u] ...

  6. HDU 3091 - Necklace - [状压DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3091 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  7. HDU 3811 Permutation 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3811 Permutation Time Limit: 6000/3000 MS (Java/Othe ...

  8. HDU 5838 (状压DP+容斥)

    Problem Mountain 题目大意 给定一张n*m的地图,由 . 和 X 组成.要求给每个点一个1~n*m的数字(每个点不同),使得编号为X的点小于其周围的点,编号为.的点至少大于一个其周围的 ...

  9. hdu 4628 Pieces 状压dp

    题目链接 枚举所有状态, 1表示这个字符还在原来的串中, 0表示已经取出来了. 代码中j = (j+1)|i的用处是枚举所有包含i状态的状态. #include <iostream> #i ...

随机推荐

  1. Entity Framework技巧系列之十二 - Tip 46 - 50

    提示46. 怎样使用Code-Only排除一个属性  这次是一个真正简单的问题,由StackOverflow上这个问题引出.  问题:  当我们使用Code-Only把一个类的信息告诉Entity F ...

  2. nefu 115 斐波那契的整除

    Description 已知斐波那契数列有如下递归定义,f(1)=1,f(2)=1, 且n>=3,f(n)=f(n-1)+f(n-2),它的前几项可以表示为1, 1,2 ,3 ,5 ,8,13, ...

  3. SharePoint 2013 APP 开发示例 (二)获取用户信息

    SharePoint 2013 APP 开发示例 (二)获取用户信息 这个示例里,我们将演示如何获取用户信息: 1. 打开 Visual Studio 2012. 2. 创建一个新的  SharePo ...

  4. js跨域访问,No ‘Access-Control-Allow-Origin‘ header is present on

    在本地用ajax跨域访问请求时报错: XMLHttpRequest cannot loadhttp://www.zjblogs.com/. No 'Access-Control-Allow-Origi ...

  5. vb6学习心路

    1.不能加载 'MSCOMCTL.OCX'--继续加载工程吗解决办法:新建一个VB工程,然后按CTRL + T,选中 “Microsoft Windows Common Controls 6.0” 然 ...

  6. perl中my和our的区别分析

    来源: http://www.jb51.net/article/35528.htm perl中our的用法require 5.006当版本号小于 5.006 的时候,会返回失败,从而导致模块加载失败. ...

  7. 使用VS软件打开网站在浏览器浏览的方法

    1.用VS软件打开网站之后,先检查网站是否使用IIS Express开发 2.若不是,则切换成使用IIS Express开发 3.检查项目使用的托管管道模式设置为经典模式了没有 4.最后选择“在浏览器 ...

  8. FRAM 铁电存储器

    铁电存储器与传统存储器的区别. 一:易失性的存储器包括静态存储器SRAM和动态存储器DRAM.           优点:读写速度快,读写寿命无次数限止.           缺点:掉电会丢失数据.  ...

  9. Hibernate 系列教程5-双向多对一

    主要讲解inverse和cascade的用法 cascade定义的是关系两端对象到对象的级联关系: 而inverse定义的是关系和对象的级联关系(管理外键的值). inverse 属性默认是false ...

  10. 转:设置Loadrunner负载机临时文件目录

    最近在跑稳定性测试 3 X 24小时的时候,发现负载机产生的日志还运行记录等等竟然有100多G! C盘空间不足,但是D盘还有700多G空间呢,怎么让临时文件转移到D盘? 此处分两种情况: 一. 修改本 ...