【暑假】[深入动态规划]UVAlive 4794 Sharing Chocolate
UVAlive 4794 Sharing Chocolate
题目:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12055
思路:
设d[S][r][c]表示形如r*c的矩形是否可以划分为S中的子集,10表示可否。
转移方程:
d[S][r][c] = d[S0][r0][c] || d[S0][r][c0]
优化:
首先注意到S r c三者知二求一,所以将状态优化为d[S][x]表示有短边x的矩形是否可以分为S的子集,长边==sum(S)/x ,这样恰好迎合了另外一个优化——只计算r*c==S的状态。
代码:
#include<iostream>
#include<cstring>
using namespace std; const int maxn = +;
const int maxw = + ; int d[<<maxn][maxw],vis[<<maxn][maxw];
int sum[<<maxn];
int kase=; inline int bitcount(int x) { return x==?:bitcount(x/)+(x&); } int dp(int s,int x) {
if(vis[s][x]==kase) return d[s][x]; //记忆化搜索
vis[s][x]=kase;
if(bitcount(s)==) return d[s][x]=; //搜索边界 int& ans=d[s][x];
int y=sum[s]/x; //根据s与x计算y
for(int s0=(s-)&s;s0;s0=(s0-)&s) { //枚举子集 //一刀
int s1=s-s0; //划分成两个子集
if(sum[s0]%x== && dp(s0,min(x,sum[s0]/x)) && dp(s1,min(x,sum[s1]/x)) ) return ans=; //是纵向一刀
if(sum[s0]%y== && dp(s0,min(y,sum[s0]/y)) && dp(s1,min(y,sum[s1]/y)) ) return ans=; //抑或横向一刀
//如果有一种切法 分成的两个子矩形YES的话那么该矩阵为YES
} return ans=;
} int main() {
ios::sync_with_stdio(false);
int n,x,y;
int A[maxn];
memset(vis,,sizeof(vis)); while(cin>>n && n) {
cin>>x>>y;
for(int i=;i<n;i++) cin>>A[i]; int full=(<<n)-;
for(int s=;s<=full;s++){ //离线计算集合s之和
sum[s]=;
for(int j=;j<n;j++) if(s&(<<j)) sum[s] += A[j];
} int ans;
if(sum[full]!=x*y || sum[full]%x!=) ans=; //面积相等且形如x*y
else
ans=dp(full,min(x,y)); cout<<"Case "<<++kase<<": ";
cout<<(ans? "YES" : "No")<<"\n";
}
return ;
}
【暑假】[深入动态规划]UVAlive 4794 Sharing Chocolate的更多相关文章
- UVALive 4794 Sharing Chocolate
Sharing Chocolate Chocolate in its many forms is enjoyed by millions of people around the world ever ...
- UVALive 4794 Sharing Chocolate(状压,枚举子集)
n的规模可以状压,f[x][y][S]表示x行,y列,S集合的巧克力能否被切割. 预处理出每个状态S对应的面积和sum(S),对于一个合法的状态一定满足x*y=sum(S),实际上只有两个变量是独立的 ...
- UVALive 4794 Sharing Chocolate DP
这道题目的DP思想挺先进的,用状态DP来表示各个子巧克力块.原本是要 dp(S,x,y),S代表状态,x,y为边长,由于y可以用面积/x表示出来,就压缩到了只有两个变量,在转移过程也是很巧妙,枚举S的 ...
- LA 4794 Sharing Chocolate
大白书中的题感觉一般都比较难,能理解书上代码就已经很不错了 按照经验,一般数据较小的题目,都有可能是用状态压缩来解决的 题意:问一个面积为x×y的巧克力,能否切若干刀,将其切成n块面积为A1,A2,, ...
- LA 4794 - Sharing Chocolate dp
题意 有一块\(x*y\)的巧克力,问能否恰好分成n块,每块个数如下 输入格式 n x y a1 a2 a3 ... an 首先\(x \times y 必然要等于 \sum\limits_{i=1} ...
- UVa Live 4794 - Sharing Chocolate 枚举子集substa = (s - 1) & substa,记忆化搜索 难度: 2
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- 【暑假】[深入动态规划]UVAlive 3983 Robotruck
UVAlive 3983 Robotruck 题目: Robotruck Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format ...
- 2015暑假训练(UVALive 5983 - 5992)线段树离线处理+dp
A: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83690#problem/A 题意:N*M的格子,从左上走到右下,要求在每个点的权值 ...
- UVa 1009 Sharing Chocolate (数位dp)
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
随机推荐
- Clojure语法学习-循环
do和块语句 在Scala中,花括号{}括起来的语句构成一个block,它的值就是最后一个语句的值. scala> val a = { | println("a") | 1} ...
- Flume学习——BasicTransactionSemantics
org.apache.flume.channel.BasicTransactionSemantics An implementation of basic Transaction semantics ...
- linux samba.tar.gz安装和配置
安装步骤: 1. tar -xzvf samba-3.5.10.tar.gz2. cd samba-3.5.103. cd source34. ./autogen.sh 如果出现:./autogen ...
- 一周一话题之四(JavaScript、Dom、jQuery全面复习总结<Dom篇>)
-->目录导航 一. 初探Dom 1. Dom介绍 二. Dom基础 1. window顶级对象 2. body.document对象事件 3. 通用的HTML元素的事件 4. 冒泡事件 5. ...
- linux下使用yum安装mysql、tomcat、httpd
一.linux下使用yum安装mysql 1.安装 查看有没有安装过: yum list installed mysql* rpm -qa | grep m ...
- 24点C++程序实现 编程之美1.16
解法1,对于任意输入的四个数字,给出一个24点的解法,若无解,则没有输出. 原理参照下图(编程之美原书) 代码如下,仅供参考 // 1.16.cpp : Defines the entry point ...
- size_t和ssize_t
Ssize_t 与size_t 跟踪linux源码得到以下宏: #ifndef _SIZE_T #define _SIZE_T typedef __kernel_size_t size ...
- 获取html上元素的真正坐标
使用HTML元素的style.left,style.top,style.width,style.height以及width,height属性,都不能获得元素的真正位置与大小,这些属性取出来的都是原来的 ...
- 如何将一个Form中的代码拆分到多个文件中
https://social.msdn.microsoft.com/Forums/en-US/64c77755-b0c1-4447-8ac9-b5a63a681b78/partial-class-fo ...
- ListView使用CursorAdapter增加和删除item
@Override protected void onCreate(Bundle savedInstanceState) { // TODO 自动生成的方法存根 super.onCreate(save ...