方格取数(1)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8851    Accepted Submission(s): 3386

Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
 
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
 
Output
对于每个测试实例,输出可能取得的最大的和
 
Sample Input
3
75 15 21
75 15 28
34 70 5
 
Sample Output
188
 
Author
ailyanlu
 
Source
 
Recommend
前面的骨牌堆放由于数据不是很大用暴力状压就过去了这个题目如果还是O(2^n*2^n*m)
得话复杂度显然爆炸,所以采用轮廓线dp的思想,O(n*m*2^(n))
对于每个格子影响他的只有四周相邻的格子,我们从左至右,由上而下递推得话,对于正在处理的格子,影响他的最多只有左边相邻和上方相邻的格子,
我们不妨以n为轮廓线长度,对于每个格子有两种操作,取or不取,不取得话可由任意状态得到,取得话只要左方&&上方状态为0表示不取即可
对于当前处理的格子我们枚举上个轮廓线的状态看是否能转移到当前轮廓线,如果可以,update即可。
最后遍历一遍得到答案。
之所以复杂度变低是采取了我为人人的方法,少遍历一遍2^n,很巧妙的思想,我会把骨牌堆放以这种方法再做一次。
#include<bits/stdc++.h>
using namespace std;
int
ans;
int
dp[][(<<)+];
bool
judge(int a,int b){return (a&(<<b));}
int
clr(int a,int b){ if(judge(a,b)){return (a^(<<b));}
else return
a;}
void
update(int cur,int now,int pre,int num)
{

dp[cur][now]=max(dp[cur][now],dp[-cur][pre]+num); //我为人人
}

int
main()
{

int
e[][],i,j,k,s,t,n;
while
(cin>>n){int cur=;
for
(i=;i<n;++i)
for
(j=;j<n;++j)
cin>>e[i][j];
memset(dp,,sizeof(dp));
for
(i=;i<n;++i){
for
(j=;j<n;++j){
cur^=;memset(dp[cur],,sizeof(dp[cur]));
for
(k=;k<(<<n);++k){
update(cur,clr(k<<,n),k,);
if
(!j){
if
(!judge(k,n-)){
update(cur,clr((k<<)+,n),k,e[i][j]);
}
}

else
{
if
((!judge(k,))&&(!judge(k,n-))){
update(cur,clr((k<<)+,n),k,e[i][j]);
}
}
}
}
}

ans=;
for
(i=;i<(<<n);++i) ans=max(ans,dp[cur][i]);
cout<<ans<<endl;
}

return
;
}
 

 

 



 

Given a rectangular grid, with dimensions

m


n

, compute the number of ways of completely tiling it

with dominoes. Note that if the rotation of one tiling matches another, they still count as different

ones. A domino is a shape formed by the union of two unit squares meeting edge-to-edge. Equivalently,

it is a matching in the grid graph formed by placing a vertex at the center of each square of the region

and connecting two vertices when they correspond to adjacent squares. An example of a tiling is shown

below.

Input

The input will consist of a set of lines with

mn

, given the restriction

n


m<

101.

Output

For each line of input, output the number of tilings in a separate line.

Sample Input

2 10

4 10

8 8

Sample Output

89

18061

12988816

 
题目不再赘述就是骨牌放置问题,这里采用轮廓线dp
要注意的就是横放时列数不能为1,竖放时行不能为1,md最近一直犯zz错误,cout ans数组我一直cout dp数组检查半天mb
#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL dp[2][(1<<11)];
LL ans[101][101];
bool judge(int a,int b){return (a&(1<<b));}
int clr(int a,int b){return (a>>b)?(a^(1<<b)):a;}
void update(int cur,int now,int pre) { dp[cur][now]+=dp[1-cur][pre]; }
int main()
{
int i,j,k,n,m,s,t;
memset(ans,-1,sizeof(ans));
while(cin>>n>>m){int cur=0;
memset(dp,0,sizeof(dp));
if(n*m%2==1) {puts("0");continue;}
if(ans[n][m]+1) {cout<<ans[n][m]<<endl;continue;}
if(m>n) swap(m,n);
dp[cur][(1<<m)-1]=1;
for(i=1;i<=n;++i){
for(j=1;j<=m;++j){cur^=1;memset(dp[cur],0,sizeof(dp[cur]));
for(k=0;k<(1<<m);++k){
if(judge(k,m-1)) update(cur,clr((k<<1),m),k); //不放
if(i>1&&!judge(k,m-1)) update(cur,(k<<1)^1,k); //竖放
if(j>1&&(!judge(k,0))&&judge(k,m-1)) update(cur,clr((k<<1)^3,m),k); //横放
}
}
}
ans[n][m]=ans[m][n]=dp[cur][(1<<m)-1];
cout<<ans[n][m]<<endl;
}
return 0;
}


HDU1565 方格取数 &&uva 11270 轮廓线DP的更多相关文章

  1. HDU1565 方格取数(1) —— 状压DP or 插头DP(轮廓线更新) or 二分图点带权最大独立集(最小割最大流)

    题目链接:https://vjudge.net/problem/HDU-1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory L ...

  2. HDU1565 方格取数(1)(状态压缩dp)

    题目链接. 分析: 说这题是状态压缩dp,其实不是,怎么说呢,题目数据太水了,所以就过了.手动输入n=20的情况,超时.正解是网络流,不太会. A这题时有个细节错了,是dp[i][j]还是dp[i][ ...

  3. Hdu-1565 方格取数(1) (状态压缩dp入门题

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  4. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  5. HDU-1565 方格取数(1)

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Me ...

  6. hdu 1565 方格取数(1) 状态压缩dp

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. hdu 2167 方格取数 【状压dp】(经典)

    <题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的  3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数 ...

  8. UVA - 11270 轮廓线DP

    其实这题还能用状压DP解决,可是时间达到2000ms只能过掉POJ2411.状压DP解法详见状压DP解POJ2411 贴上POJ2411AC代码 : 2000ms 时间复杂度h*w*(2^w)*(2^ ...

  9. TYVJ 1011 NOIP 2008&&NOIP 2000 传纸条&&方格取数 Label:多线程dp

    做题记录:2016-08-15 15:47:07 背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...

随机推荐

  1. poj3171 Cleaning Shifts【线段树(单点修改区间查询)】【DP】

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4422   Accepted: 1482 D ...

  2. Golang学习-第二篇 搭建一个简单的Go Web服务器

    序言 由于本人一直从事Web服务器端的程序开发,所以在学习Golang也想从Web这里开始学起,如果对Golang还不太清楚怎么搭建环境的朋友们可以参考我的上一篇文章 Golang的简单介绍及Wind ...

  3. SpringBoot项目属性配置

    如果使用IDEA创建Springboot项目,默认会在resource目录下创建application.properties文件,在SpringBoot项目中,也可以使用yml类型的配置文件代替pro ...

  4. python中super的使用

    转自:http://python.jobbole.com/86787/ super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能, ...

  5. vue - 指令系统

    指令系统: 所谓指令系统,大家可以联想咱们的cmd命令行工具,只要我输入一条正确的指令,系统就开始干活了. 在vue中,指令系统,设置一些命令之后,来操作我们的数据属性,并展示到我们的DOM上. 1. ...

  6. tow sum

    今天面试好打脸!!! 解决方案方法一:暴力法暴力法很简单.遍历每个元素 xx,并查找是否存在一个值与 target−x 相等的目标元素. public int[] twoSum(int[] nums, ...

  7. Python开发【Django】:缓存、信号

    缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache ...

  8. Java调用Python脚本并获取返回值

    在Java程序中有时需要调用Python的程序,这时可以使用一般的PyFunction来调用python的函数并获得返回值,但是采用这种方法有可能出现一些莫名其妙的错误,比如ImportError.在 ...

  9. 装饰器的修复wraps,偏函数partial 以及chain

    将被装饰的函数的一些属性值赋值给 装饰器函数,最终让属性的显示更符合我们的直觉. from functools import wraps def wapper(func): @wraps(func) ...

  10. 26. Remove Duplicates from Sorted Array(删除排序数组中的重复元素,利用排序的特性,比较大小)

      Given a sorted array, remove the duplicates in-place such that each element appear only once and r ...