UVALive 4794 Sharing Chocolate DP
这道题目的DP思想挺先进的,用状态DP来表示各个子巧克力块。原本是要 dp(S,x,y),S代表状态,x,y为边长,由于y可以用面积/x表示出来,就压缩到了只有两个变量,在转移过程也是很巧妙,枚举S的子集s0,然后 s1=S-s0来代表除该子集的另一个集合,接下来分两种情况,如果这个子集是通过把 S保留x,切割y,则转移到dp(s0,x)和dp(s1,x),另一种情况是转移到dp(s0,y)和dp(s1,y)。为了更加缩小状态,统一把转移方程的 x换成 min(x,sum[S]/x),sum为该状态下的面积
#include <cstdio>
#include <cstring>
#include <algorithm>
//#include <cmath>
#define N 1<<17
using namespace std;
int f[N][],sum[N];
int A[],vis[N][];
int ok(int x) //测试当前状态下是否只剩下一种巧克力,是的话,二进制状态里必定只有一个1,因此只会返回1 否则则返回其他值.
{
if (x==) return ;
return ok(x/)+(x&);//这里导致我WA了好几次,原因是没注意&的优先级低,要括号起来
}
int dp(int S,int x)
{
if (vis[S][x]) return f[S][x];
vis[S][x]=;
//int& ans=f[S][x];
if (ok(S)==) return f[S][x]=; //如果满足,则说明以及到达某块具体巧克力的状态,完成任务 return 1回去
int y=sum[S]/x;
for (int s0=S&(S-);s0;s0=S&(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 f[S][x]=;//这里分两种情况,分别代表两个子集的产生 是切割y 或者 切割x产生的
if (sum[s0]%y== && dp(s0,min(y,sum[s0]/y))&& dp(s1,min(y,sum[s1]/y)))
return f[S][x]=;
}
return f[S][x]=; }
int main()
{
int kase=,n,x,y;
while (scanf("%d",&n)!=EOF)
{
if (n==) break;
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];
}
}
}
memset(vis,,sizeof vis);
int all=(<<n)-;
int ans=;
if (sum[all]!=x*y || sum[all]%x!=)
{
ans=;
}
else
{
ans=dp(all,min(x,y));
}
printf("Case %d: %s\n",++kase,ans==? "Yes":"No");
}
return ;
}
UVALive 4794 Sharing Chocolate DP的更多相关文章
- 【暑假】[深入动态规划]UVAlive 4794 Sharing Chocolate
UVAlive 4794 Sharing Chocolate 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12055 ...
- UVALive 4794 Sharing Chocolate
Sharing Chocolate Chocolate in its many forms is enjoyed by millions of people around the world ever ...
- LA 4794 - Sharing Chocolate dp
题意 有一块\(x*y\)的巧克力,问能否恰好分成n块,每块个数如下 输入格式 n x y a1 a2 a3 ... an 首先\(x \times y 必然要等于 \sum\limits_{i=1} ...
- UVALive 4794 Sharing Chocolate(状压,枚举子集)
n的规模可以状压,f[x][y][S]表示x行,y列,S集合的巧克力能否被切割. 预处理出每个状态S对应的面积和sum(S),对于一个合法的状态一定满足x*y=sum(S),实际上只有两个变量是独立的 ...
- LA 4794 Sharing Chocolate
大白书中的题感觉一般都比较难,能理解书上代码就已经很不错了 按照经验,一般数据较小的题目,都有可能是用状态压缩来解决的 题意:问一个面积为x×y的巧克力,能否切若干刀,将其切成n块面积为A1,A2,, ...
- 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 ...
- UVa 1009 Sharing Chocolate (数位dp)
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
- UVALive - 6952 Cent Savings dp
题目链接: http://acm.hust.edu.cn/vjudge/problem/116998 Cent Savings Time Limit: 3000MS 问题描述 To host a re ...
- UVALive - 6529 找规律+dp
题目链接: http://acm.hust.edu.cn/vjudge/problem/47664 Eleven Time Limit: 5000MS 问题描述 In this problem, we ...
随机推荐
- VS2019 添加控制器 主机运行转换时出现问题
问题: 解决方案: 更换低版本VS,亲测VS2017可行(其它未实测) VS2019目前没找到解决方案,VS版本问题 原文链接
- Html5 自学笔记
1 html的全称 Hyper Text Markup Language 2 HTML的意义 使用标记标签( Markup Tag)来描述网页 3 HTML标签一定成对吗 是 4 <html ...
- c++链接mysql5.7
1.单独安装mysql5.7 phpstudy安装的没有include和lib文件夹2.vs2013中右键属性 项目 - C/C++ - 常规 - 附加包含目录 里面添加 D:\**\include ...
- 简单javascript学习总结
2019-10-19 //文章汇总于绿叶学习网 console.log() //控制台输出 目录 数据类型:.... 2 函数:.... 3 ...
- JAVA作用域和排序算法介绍
一.作用域 1.作用域的概念 所谓的作用域是指引用可以作用到的范围. 一个引用的作用域是从引用定义位置到包裹它的最近的大括号的结束位置.只有在作用域范围内才可以访问到引用,超出作用域无法访问引用. 定 ...
- canvas背景粒子动态变化动画
var canvas = document.getElementById("cas"); var ctx = canvas.getContext("2d"); ...
- 【LeetCode】160. 相交链表
题目 输入两个链表,找出它们的第一个公共节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB ...
- Linux基础学习准备
Linux 基础学习准备 工欲善其事必先利其器,还是买个服务器折腾比较好. 虚拟机和镜像 推荐吾爱的:吾爱虚拟机2.0 CentOS镜像: Centos国内下载源 http://man.linuxde ...
- C/C++ SQLite 之基础篇
文章目录: 1. 下载 SQLite3 源码: 2. 下载 SQLite3.dll 文件: 3. 生成 SQLite3.lib 文件 : 4. 生成或者下载 SQL ...
- Database--事务
参考 https://segmentfault.com/a/1190000012669504?utm_source=tag-newest https://blog.csdn.net/qq_371559 ...