题目链接:

  https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3540

题目大意:

  给一块长x,宽y的巧克力,和一个数组A={a1, a2, …,an},问能否经过若干次切分后,得到面积分别为a1,a2,…an的n块巧克力。每次切分只可以选择一块巧克力,将其分为两半,如下图,3×4的巧克力经过切分后,可以得到面积分别为6,3,2,1的巧克力。

解题思路:

  假设能得到n块小巧克力,考虑切分的过程,第一次切分后巧克力被分为两部分,最终结果中的任一快巧克力a[i]要么来自第一部分,要么来自第二部分,即两部分分别对应一个A的子集。那么枚举A的子集A0,另A1=A-A0,如果能找到当前巧克力的一种切分方式,让第一部分能分成A0对应的小巧克力,第二部分分成A1对应的小巧克力,则找到了一组合法的解。

  定义dp状态如下,dp[x][S](S是二进制表示的集合)表示边长分别为x, S对应面积/x的巧克力能否切分成S对应集合,若能则为1,否则为0。考虑到边长x*y=面积,因此只保留一个边长,另一边可以求出来。

  此代码中枚举子集的方法是数位dp的一个技巧。

参考代码:

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 16 bool f[][<<N];
bool vis[][<<N];
int A[N], sum[<<N];
int cntbit(int x)
{
int ret = ;
while(x) ret += x&, x >>= ;
return ret;
} bool dp(int x, int cur)//cur用二进制表示当前集合
{
if(vis[x][cur] == ) return f[x][cur];
vis[x][cur] = ;
bool &ans = f[x][cur];
int y = sum[cur]/x;
if(cntbit(cur) == )
{
vis[x][cur] = ;
return ans = true;
}
for(int s0 = (cur-)&cur; s0; s0 = (s0-) & cur)//枚举子集的方法
{
int s1 = cur-s0;
if(sum[s0]%x == && dp(min(x, sum[s0]/x), s0) && dp(min(x, sum[s1]/x), s1))
return ans = ;
if(sum[s0]%y == && dp(min(y, sum[s0]/y), s0) && dp(min(y, sum[s1]/y), s1))
return ans = ;
}
return ans = ;
} int main()
{
int n, x, y, cas = ;
while(~scanf("%d", &n), n)
{
scanf("%d %d", &x, &y);
for(int i = ; i < n; i++) scanf("%d", &A[i]); memset(sum, , sizeof(sum));
for(int i = ; i < (<<n); i++)
for(int j = ; j < n; j++) if(i&(<<j)) sum[i] += A[j]; int d = (<<n)-;
if(sum[d] != x*y)
{
printf("Case %d: No\n", cas++);
continue;
} memset(vis, , sizeof(vis));
bool ans = dp(min(x, y), d);
printf("Case %d: ", cas++);
puts(ans ? "Yes" : "No");
}
return ;
}

UVa 1009 Sharing Chocolate (数位dp)的更多相关文章

  1. uva 10712 - Count the Numbers(数位dp)

    题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a.b.问说在a到b之间有多少个n. 解题思路:数位dp.dp[i][j][x][y]表示第i位为j的时候.x是 ...

  2. 51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给 ...

  3. 51nod 1009 数位dp入门

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 1009 数字1的数量 基准时间限制:1 秒 空间限制:13107 ...

  4. uva 10817(数位dp)

    uva 10817(数位dp) 某校有m个教师和n个求职者,需讲授s个课程(1<=s<=8, 1<=m<=20, 1<=n<=100).已知每人的工资c(10000 ...

  5. 51nod 1009 数字1的数量(数位dp模板)

    给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1.   数位dp的模板题   ...

  6. 1009 数字1的数量 数位dp

    1级算法题就这样了,前途渺茫啊... 更新一下博客,我刚刚想套用数位dp的模板,发现用那个模板也是可以做到,而且比第二种方法简单很多 第一种方法:我现在用dp[pos][now]来表示第pos位数字为 ...

  7. 51Nod 1009 数字1的个数 | 数位DP

    题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9 ...

  8. 【数位dp】UVA - 11361 - Investigating Div-Sum Property

    经典数位dp!而且这好像是数位dp的套路板子……不需要讨论原来我很头疼的一些边界. 改天用这个板子重做一下原来的一些数位dp题目. http://blog.csdn.net/the_useless/a ...

  9. UVA - 1640 The Counting Problem (数位dp)

    题意:统计l-r中每种数字出现的次数 很明显的数位dp问题,虽然有更简洁的做法但某人已经习惯了数位dp的风格所以还是选择扬长避短吧(说白了就是菜啊) 从高位向低位走,设状态$(u,lim,ze)$表示 ...

随机推荐

  1. h5离线缓存

    离线缓存:application cache 什么是离线缓存: 离线缓存可以将站点的一些文件缓存到本地,它是浏览器自己的一种机制,将需要的文件缓存下来,以便后期即使没链接网络,被缓存的页面也可以展示 ...

  2. ClientDataSet初步使用

    https://blog.csdn.net/onebigday/article/details/5602619 ClientDataSet初步使用 2010年05月18日 08:36:00 阅读数:5 ...

  3. python 操作openpyxl导出Excel 设置单元格格式以及合并处理

    贴上一个例子,里面设计很多用法,根据将相同日期的某些行合并处理. from openpyxl import Workbook from openpyxl.styles import Font, Fil ...

  4. 记一次oracle安装错误:INFO: //usr/lib64/libstdc++.so.5: undefined reference to `memcpy@GLIBC_2.14'

    --一次oracle安装错误,oracle version:11.2.0.1.0[root@localhost ~]# cat /etc/issue\SKernel \r on an \m [root ...

  5. vue-methods方法与computed计算属性的差别

    好吧,我就是单纯的举个例子:实现显示变量 message 的翻转字符串 第一种:methods:我们可以通过在表达式中调用方法来达到同样的效果: 第二种:computed:计算属性 上面的2中方法都实 ...

  6. 解决ajax跨域几种方式

    发生跨域问题的原因: 浏览器的限制,出于安全考虑.前台可以正常访问后台,浏览器多管闲事报跨域问题,但其实前台已经访问到后台了. 跨域,协议.域名.端口任何一个不一样浏览器就认为是跨域. XHR(XML ...

  7. python基础-4.1 open 打开文件练习:修改haproxy配置文件

    1.如何在线上环境优雅的修改配置文件? 配置文件名称ini global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 in ...

  8. Vue 基础 day05 webpack 3.x

    什么是webpack webpack 是前端的一个项目构建工具, 它是基于 Node.js 开发出来的一个前端工具 借助于webpack这个前端自动化构建工具, 可以完美实现资源的合并.打包.压缩.混 ...

  9. Docker中使用多阶段Dockerfile构建容器镜像image(镜像优化)

    使用多阶段构建 预计阅读时间: 6分钟 多阶段构建是守护程序和客户端上需要Docker 17.05或更高版本的新功能.多阶段构建对于那些努力优化Dockerfiles同时使其易于阅读和维护的人来说非常 ...

  10. Python - pycharm 代码自动补全

    有很多人说是代码补全功能未打开,的确,代码补全功能确实要打开才能用,打开方法 file---->power save mode,把这个前面的√号去掉即可