题意

  有一块\(x*y\)的巧克力,问能否恰好分成n块,每块个数如下

输入格式

n

x y

a1 a2 a3 ... an

首先\(x \times y 必然要等于 \sum\limits_{i=1}^{n}a_i\)

设集合状态为S,则转移方程为

\(f(x,y,S)=(f(x,c_0,S_0)\&\& f(x,y-c_0,S_1))\|(f(c_0,y,S_0)\&\& f(x-c_0,y,S_1)) \) 分别对应横着掰和竖着掰

由于 \(x \times y = \sum\limits_{i=1}^{n}a_i\) 故可以简化为f(x,S) x为min(x,y)

 /*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int org[];
int sum[<<],Max;
int f[][<<],vis[][<<];
int count_one(int x) //统计1的个数
{
x=(x&0x55555555)+(x>>&0x55555555);
x=(x&0x33333333)+(x>>&0x33333333);
x=(x&0x0F0F0F0F)+(x>>&0x0F0F0F0F);
x=(x&0x00FF00FF)+(x>>&0x00FF00FF);
x=(x&0x0000FFFF)+(x>>&0x0000FFFF);
return x;
}
int dp(int x,int S)
{
if(vis[x][S])return f[x][S]; //记忆化搜索
vis[x][S]=;
int &ans=f[x][S],S1,y=sum[S]/x;
ans=;
if(count_one(S)==)return ans=;
for(int S0=(S-)&S;S0;S0=(S0-)&S)
{
S1=S-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,i;
int x,y,C=;
while(~scanf("%d",&n)&&n)
{
scanf("%d%d",&x,&y);
for(i=;i<n;i++)
scanf("%d",&org[i]);
memset(vis,,sizeof(vis));
Max=(<<n)-;
int S;
for(S=;S<=Max;S++)//记录每一个状态对应的巧克力块和
{
sum[S]=;
for(i=;i<n;i++)
if(S&(<<i))sum[S]+=org[i];
}
int ans=;
if(sum[Max]==x*y)ans=dp(min(x,y),Max);
printf("Case %d: %s\n",++C,ans?"Yes":"No");
}
}

LA 4794 - Sharing Chocolate dp的更多相关文章

  1. LA 4794 Sharing Chocolate

    大白书中的题感觉一般都比较难,能理解书上代码就已经很不错了 按照经验,一般数据较小的题目,都有可能是用状态压缩来解决的 题意:问一个面积为x×y的巧克力,能否切若干刀,将其切成n块面积为A1,A2,, ...

  2. UVALive 4794 Sharing Chocolate DP

    这道题目的DP思想挺先进的,用状态DP来表示各个子巧克力块.原本是要 dp(S,x,y),S代表状态,x,y为边长,由于y可以用面积/x表示出来,就压缩到了只有两个变量,在转移过程也是很巧妙,枚举S的 ...

  3. 【暑假】[深入动态规划]UVAlive 4794 Sharing Chocolate

    UVAlive 4794 Sharing Chocolate 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12055 ...

  4. UVALive 4794 Sharing Chocolate

    Sharing Chocolate Chocolate in its many forms is enjoyed by millions of people around the world ever ...

  5. 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 ...

  6. UVALive 4794 Sharing Chocolate(状压,枚举子集)

    n的规模可以状压,f[x][y][S]表示x行,y列,S集合的巧克力能否被切割. 预处理出每个状态S对应的面积和sum(S),对于一个合法的状态一定满足x*y=sum(S),实际上只有两个变量是独立的 ...

  7. LA 4794 状态DP+子集枚举

    状态压缩DP,把切割出的面积做状态压缩,统计出某状态下面积和. 设f(x,y,S)为在状态为S下在矩形x,y是否存在可能划分出S包含的面积.若S0是S的子集,对矩形x,y横切中竖切,对竖切若f(x,k ...

  8. UVa 1009 Sharing Chocolate (数位dp)

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  9. HDU 5745 La Vie en rose (DP||模拟) 2016杭电多校联合第二场

    题目:传送门. 这是一道阅读理解题,正解是DP,实际上模拟就能做.pij+1 指的是 (pij)+1不是 pi(j+1),判断能否交换输出即可. #include <iostream> # ...

随机推荐

  1. 混血儿爹妈要混的远,数据库与WEB分离,得混的近

    最近搞了个漫画网站,放在香港VPS,由于内存不够,把数据库移到了阿里云,混的远了点,没缓存的时候网站打开速度慢了1秒左右.笨狗漫画:http://www.bengou8.com 底部有sql时间cop ...

  2. C++库研究笔记——Linux下是否需要使用memory pool?

    Linux Slab分配器(一)--概述 Linux slab 分配器剖析 C++库研究笔记——内存池实现 做了一些测试:发现linux使用内存池与否没有明显差别,仅仅有2倍. Linux内存处理机制 ...

  3. [Javascript] Advanced Reduce: Common Mistakes

    Take away: Always check you ruturn the accumulator Always pass in the inital value var data = [" ...

  4. Unix C++(boost) 线程同步和线程组

    #include <boost/thread.hpp> #include <iostream> #include <vector> #include <cst ...

  5. tortoisegit 保存用户名密码

    方法一当你配置好git后,在C:\Documents and Settings\Administrator\ 目录下有一个 .gitconfig 的文件,里面会有你先前配好的name 和email,只 ...

  6. 手机Web网站,设置拒绝电脑访问

    最近一段时间,都在使用Jquery-Mobile + MVC做手机Web,有一些心得.体会 下面介绍如何拒绝电脑访问手机网站 电脑的浏览器,跟手机的浏览器内核不一样,这是我设置拒绝访问的思路. 下面是 ...

  7. BitmapImage使用FileStream读取文件

    var bitmapImage = new BitmapImage(); using (FileStream fs = new FileStream(file.FullName, FileMode.O ...

  8. deep learning in nlp 资料文献

    Deep Learning for Natural Language Processing (without Magic) http://nlp.stanford.edu/courses/NAACL2 ...

  9. 传输层-UDP

    传输层构建在网络层之上,传输层提供端口到端口之间的通讯. 传输层通过端口号来标识一个端口,不同于网卡,端口是逻辑上的概念.传输层的端口为16个比特(bit)长度,即最多能表示65 536个端口,端口号 ...

  10. 软件测试 homework2

    1. 程序1:   for循环的i>0改为i>=0: 程序2:   for循环for (int i = 0; i < x.length; i++)改为for (int i = x.l ...