题目链接:

  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. sqlserver 获取存储过程执行时间

    use [数据库名]   select last_execution_time '最近一次执行时间'  from sys.dm_exec_procedure_stats  where type='P' ...

  2. 关闭Linux无用端口

    关闭系统不必要的端口,增强系统安全,此处以关闭111端口为例进行说明. 1).查看本机正在监听的端口: [root@b ~]# netstat -tlnup Active Internet conne ...

  3. Delphi XE2 之 FireMonkey 入门(30) - 数据绑定: TBindingsList: TBindExpression 的 OnAssigningValue 事件

    Delphi XE2 之 FireMonkey 入门(30) - 数据绑定: TBindingsList: TBindExpression 的 OnAssigningValue 事件 表达式中的函数有 ...

  4. 字符串中的TOUPPER函数

    std::string& str_toupper(std::string& s) { std::transform(s.begin(), s.end(), s.begin(), []( ...

  5. kali安装教程

    首先在vm里面新建虚拟机,直接选择典型,然后下一步.   1   2 然后到了这一步,选择中间的安装程序光盘镜像文件,然后去文件里面找你自己下载的镜像,这时候可能系统会出现无法检测此光盘镜像中的操作系 ...

  6. GMS测试常用命令CTS&GTS&VTS

    本文档介绍一下cts,gts,sts,vts,cts-on-gsi等测试的常用命令,基于Android9. [附件]Google官网的命令网页. 常用通用命令参数: 列出历史测试结果:l r 指定设备 ...

  7. [13期]mysql-root全手工注入写马实例实战

    回显方便的小工具

  8. Maven依赖项Scope属性设置含义

    Idea的File->Project Structure->左侧Modules: 选择自己的项目如图: 每个依赖项的Scope选项进行该jar包的相关操作设置,默认为compile,根据需 ...

  9. Django之视图(V)

    Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误, ...

  10. HDU-2571 命运(搜索,我才不是为了插图呢!哼!)

    看到这题其实感觉就是搜索题,广搜的话看讨论区里已经有人内存超限了,所以我选择了深搜,有两种思路,第一种是从起点出发,依次更新每一个格子的最大值,这样dp[n][m]就是最后的结果了,第二种是从起点试探 ...