UVa 1009 Sharing Chocolate (数位dp)
题目链接:
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)的更多相关文章
- 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是 ...
- 51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给 ...
- 51nod 1009 数位dp入门
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 1009 数字1的数量 基准时间限制:1 秒 空间限制:13107 ...
- uva 10817(数位dp)
uva 10817(数位dp) 某校有m个教师和n个求职者,需讲授s个课程(1<=s<=8, 1<=m<=20, 1<=n<=100).已知每人的工资c(10000 ...
- 51nod 1009 数字1的数量(数位dp模板)
给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. 数位dp的模板题 ...
- 1009 数字1的数量 数位dp
1级算法题就这样了,前途渺茫啊... 更新一下博客,我刚刚想套用数位dp的模板,发现用那个模板也是可以做到,而且比第二种方法简单很多 第一种方法:我现在用dp[pos][now]来表示第pos位数字为 ...
- 51Nod 1009 数字1的个数 | 数位DP
题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9 ...
- 【数位dp】UVA - 11361 - Investigating Div-Sum Property
经典数位dp!而且这好像是数位dp的套路板子……不需要讨论原来我很头疼的一些边界. 改天用这个板子重做一下原来的一些数位dp题目. http://blog.csdn.net/the_useless/a ...
- UVA - 1640 The Counting Problem (数位dp)
题意:统计l-r中每种数字出现的次数 很明显的数位dp问题,虽然有更简洁的做法但某人已经习惯了数位dp的风格所以还是选择扬长避短吧(说白了就是菜啊) 从高位向低位走,设状态$(u,lim,ze)$表示 ...
随机推荐
- h5离线缓存
离线缓存:application cache 什么是离线缓存: 离线缓存可以将站点的一些文件缓存到本地,它是浏览器自己的一种机制,将需要的文件缓存下来,以便后期即使没链接网络,被缓存的页面也可以展示 ...
- ClientDataSet初步使用
https://blog.csdn.net/onebigday/article/details/5602619 ClientDataSet初步使用 2010年05月18日 08:36:00 阅读数:5 ...
- python 操作openpyxl导出Excel 设置单元格格式以及合并处理
贴上一个例子,里面设计很多用法,根据将相同日期的某些行合并处理. from openpyxl import Workbook from openpyxl.styles import Font, Fil ...
- 记一次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 ...
- vue-methods方法与computed计算属性的差别
好吧,我就是单纯的举个例子:实现显示变量 message 的翻转字符串 第一种:methods:我们可以通过在表达式中调用方法来达到同样的效果: 第二种:computed:计算属性 上面的2中方法都实 ...
- 解决ajax跨域几种方式
发生跨域问题的原因: 浏览器的限制,出于安全考虑.前台可以正常访问后台,浏览器多管闲事报跨域问题,但其实前台已经访问到后台了. 跨域,协议.域名.端口任何一个不一样浏览器就认为是跨域. XHR(XML ...
- python基础-4.1 open 打开文件练习:修改haproxy配置文件
1.如何在线上环境优雅的修改配置文件? 配置文件名称ini global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 in ...
- Vue 基础 day05 webpack 3.x
什么是webpack webpack 是前端的一个项目构建工具, 它是基于 Node.js 开发出来的一个前端工具 借助于webpack这个前端自动化构建工具, 可以完美实现资源的合并.打包.压缩.混 ...
- Docker中使用多阶段Dockerfile构建容器镜像image(镜像优化)
使用多阶段构建 预计阅读时间: 6分钟 多阶段构建是守护程序和客户端上需要Docker 17.05或更高版本的新功能.多阶段构建对于那些努力优化Dockerfiles同时使其易于阅读和维护的人来说非常 ...
- Python - pycharm 代码自动补全
有很多人说是代码补全功能未打开,的确,代码补全功能确实要打开才能用,打开方法 file---->power save mode,把这个前面的√号去掉即可