题目链接:

  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. (转)C#_WinForm接收命令行参数

    本文转载自:http://blog.csdn.net/lysc_forever/article/details/38356007 首先,我要仔细的声明下,本文讲的是接受命令行参数,让程序启动.而不是启 ...

  2. debian 配置静态ip

    1. 查看虚拟机上本机ipcmd→ipconfig 2. 配置网卡2.1 备份原有配置文件配置文件cp /etc/network/interfaces /etc/network/interfacesb ...

  3. jmeter模拟spike尖峰测

    jmeter模拟spike尖峰测试 概述 尖峰测试(Spike testing)在性能测试中属于压力测试的一个子集.指的是在某一瞬间或者多个频次下用户数和压力陡然增加的场景. 为了验证我们的网站在访问 ...

  4. Monte Carlo Control

    Problem of State-Value Function Similar as Policy Iteration in Model-Based Learning, Generalized Pol ...

  5. SVG.JS 画弧线

    需求描述: 使用svg.js,绘制一个弧线.下图绿色弧线. 准备工作: 1.了解SVG Path中的A指令 详细文档,请戳这里 给定x半径.y半径后,经过指定的两点,可以有2个椭圆,因此两点间有2条弧 ...

  6. mysql压缩包安装相关过程命令

    mysqld --remove mysql57 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Eventlog\Application\MySQL目 ...

  7. Hadoop运行模式:本地模式、伪分布模式、完全分布模式

    1.本地模式:默认模式 - 不对配置文件进行修改. - 使用本地文件系统,而不是分布式文件系统. - Hadoop不会启动NameNode.DataNode.ResourceManager.NodeM ...

  8. Lost Cows POJ 2182 思维+巧法

    Lost Cows POJ 2182 思维 题意 是说有n头牛,它们身高不一但是排成了一队,从左到右编号为1到n,现在告诉你从第二号开始前面的那些牛中身高小于它的个数,一共有n-1个数.然后求出它们按 ...

  9. CodeForce 855B 暴力or线段树

    CodeForce 855B 暴力or线段树 题意 给你一串数,然后找出三个数,他们的前后关系和原来一样,可以相同,然后分别乘p,q,r,求他们积的和最大,并且输出这个数. 解题思路 这个可以使用线段 ...

  10. INPUT输入子系统——按键

    一.什么是input输入子系统? 1.1. Linux系统支持的输入设备繁多,例如键盘.鼠标.触摸屏.手柄或者是一些输入设备像体感输入等等,Linux系统是如何管理如此之多的不同类型.不同原理.不同的 ...