P1504 积木城堡
原题链接 https://www.luogu.com.cn/problem/P1504
闲话时刻
这道题是一道 暴力 dp好题,dp 的方法和平常的不大一样,也许是我的脑回路清奇,总之还是值得做一下的 。
题目大意
有 n 组数,每组数都是从大到小排列(好像没什么用),现在从每组数中删去一些数使得每组数的和相等,问这个相等的和最大是多少;
题解
首先我们看到数据范围比较小,脑子中的第一个思路应该是暴力;
暴力什么呢?
一个简单的想法就是把每一组在一波瞎搞之后所能得到的所有可能的高度都记录下来,然后从大到小去枚举最后高度,如果每一组瞎搞之后都能达到这个高度,那么这个高度就是最优解了;
我的思路就是这样,只不过求每一组的所有可能的高度我是用的 dp 来求的,当然是暴力的复杂度qwq
状态设置
dp [ i ][ j ]:第 i 组的积木在瞎搞之后能否达到 j 的高度;
状态转移
假如说 dp [ i ][ j ] 是合法的,那么我们再移走一块积木 a [ k ],那么也是合法的,即:
dp [ i ][ j-a [ k ] ] = dp [ i ][ j- a [ k ] ] | dp [ i ][ j ](要么这个高度本来就合法,要么是 j 通过移走 a [ k ] 使其变得合法,所以中间是 | 运算)
枚举顺序
有个小细节就是:要先枚举每一组的积木再去枚举高度
这样的话才能保证每一块积木只可能被删除一次,如果枚举反了的话会出现一积木多用的现象;
答案
我们从大到小去枚举高度,如果存在一个高度使得每一组积木都可以拼成,那么直接输出并结束程序就OK了;
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
char ch=getchar();
int a=,x=;
while(ch<''||ch>'')
{
if(ch=='-') x=-x;
ch=getchar();
}
while(ch>=''&&ch<='')
{
a=(a<<)+(a<<)+(ch-'');
ch=getchar();
}
return a*x;
}
const int N=;
int n;
int len[N],sum[N];
int a[N][N],dp[N][N*N]; //dp[i][j]:第i个城堡进行若干操作后能否得到高度为j的情况
int main()
{
n=read();
for(int i=;i<=n;i++)
{
int x=read();
while(x!=-)
{ //len[i]:第i组积木的个数
a[i][++len[i]]=x; //a[i][j]:第i组的第j个积木的高度
sum[i]+=x; //sum[i]:第i组积木的最大高度(一个积木也没有删掉的情况)
x=read();
}
dp[i][sum[i]]=;
}
for(int i=;i<=n;i++)
for(int j=;j<=len[i];j++) //注意这里一定要先枚举每一组的积木
for(int k=;k<=sum[i];k++) //再枚举高度
dp[i][k]|=dp[i][k+a[i][j]]; //通过dp[i][k+a[i][j]]删除a[i][j]来使dp[i][k]变得合法
for(int j=;j>=;j--)
{
bool bj=;
for(int i=;i<=n;i++)
{
if(!dp[i][j]) //只要有一组拼不成就白搭
{
bj=;
break;
}
}
if(bj==) //如果都能拼成的话,此时的高度一定是最优解
{
printf("%d\n",j);
return ;
}
}
return ;
}
P1504 积木城堡的更多相关文章
- 到达型01背包---P1504 积木城堡
P1504 积木城堡 题解 到达型01背包 对于每一组城堡,它可以到达一些高度 但是我们要求的是所有背包可以到达的公共高度的最大值 f[ i ] 表示对于一组城堡,能否到达高度 j ,然后我们跑 n ...
- 洛谷P1504 积木城堡
题目描述 XC的儿子小XC最喜欢玩的游戏用积木垒漂亮的城堡.城堡是用一些立方体的积木垒成的,城堡的每一层是一块积木.小XC是一个比他爸爸XC还聪明的孩子,他发现垒城堡的时候,如果下面的积木比上面的积木 ...
- 洛谷 P1504 积木城堡
题目传送门 解题思路: 01背包. AC代码: #include<iostream> #include<cstdio> #include<vector> using ...
- VIJOS-P1059 积木城堡
洛谷 P1504 积木城堡 https://www.luogu.org/problem/P1504 JDOJ 1240: VIJOS-P1059 积木城堡 https://neooj.com/oldo ...
- vijos1059 积木城堡[n年浙江省队第X轮](背包的方案总数 or 01背包)
描述 XC的儿子小XC最喜欢玩的游戏用积木垒漂亮的城堡.城堡是用一些立方体的积木垒成的,城堡的每一层是一块积木.小XC是一个比他爸爸XC还聪明的孩子,他发现垒城堡的时候,如果下面的积木比上面的积木大, ...
- vijosP1059 积木城堡
vijosP1059 积木城堡 链接:https://vijos.org/p/1059 [思路] 01背包. 刚开始想麻烦了,想的是二分答案然后01背包判断是否可行,但是首先答案不满足单调性所以不能二 ...
- 【题解】「P1504」积木城堡
这题是01背包(\(DP\)) 如何判断要拆走那个积木,首先定义一个\(ans\)数组,来存放这对积木能拼成多高的,然后如果\(ans_i = n\)那么就说明这个高度的积木可以. 话不多说,上代码! ...
- 积木城堡(dp)
题目描述 XC的儿子小XC最喜欢玩的游戏用积木垒漂亮的城堡.城堡是用一些立方体的积木垒成的,城堡的每一层是一块积木.小XC是一个比他爸爸XC还聪明的孩子,他发现垒城堡的时候,如果下面的积木比上面的积木 ...
- SOJ 2930_积木城堡
[题意]若干个城堡,给定每个城堡的积木数及每块积木的棱长.从城堡中抽出积木使每块城堡高度相同,求最大高度 [分析]城堡的积木选择可以看成01背包问题,从最矮的城堡高度开始依次递减,求出使每个背包都能装 ...
随机推荐
- Ubuntu 18.04 LTS版本 谷歌拼音输入法安装
为何安装? 自带IBUS框架对中文支持不稳定 采用对中文支持稳定的fcitx框架 如何安装? 步骤如下: 卸载自带IBUS框架 命令:sudo remove ibus 安装fcitx框架 ...
- 【阿里云开发】- 搭建和卸载svn服务器
Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的数据. 这些数据放置在一个中央资料档案库(repository) 中.这个档案库很像一个普 ...
- JS权威指南读书笔记(五)
第十三章 Web浏览器中的JavaScript 1 在Html文档中嵌入客户端4种JS代码方法 a 内联方式,放置在<script>标签之间 b 放置在<script ...
- node+mysql+vue+express项目搭建
第一步:项目搭建之前首先需要安装node环境和MySQL数据库. 在已经完成上述的条件下开始进行以下操作: npm install @vue/cli -g (-g 代表全局安装) 初始化项目 v ...
- JAVA基础之XML相关
个人理解: 知晓XML与HTML的不同,知道其的自由性和约束的方式(规范)!数据按Schema约束写到XML里,然后通过dom4j解析出所有的元素,再用反射创建对象接着调出其所有的方法!!!特别要熟练 ...
- JAVA - Windows下JDK默认安装的配置参数
JDK版本1.8 JAVA_HOME C:\Program Files\Java\jdk1.8.0_60 CLASSPATH .;%%JAVA_HOME%%\lib;%%JAVA_HOME%%\lib ...
- android RecyclerView的Linear布局案例
1.先创建 activity_recycle_view.xml 和 activity_recycler_linear_item.xml 如下: <?xml version="1.0&q ...
- pre-departure preparation-to chengdu or shenzhen
编辑本文 (一)思想要点 1.行动改变自己,做自己的救世主. 2.成为一个技术大拿. 3.当生活吊打了你,不用悲伤,尽快反击(力所能及的做事),不要停歇,因为不能再给生活喘息的机会. 4.遇到什么问题 ...
- Python学习日记(十三) 递归函数和二分查找算法
什么是递归函数? 简单来说就是在一个函数中重复的调用自己本身的函数 递归函数在调用的时候会不断的开内存的空间直到程序结束或递归到一个次数时会报错 计算可递归次数: i = 0 def func(): ...
- UEditor 在 Layer 模态框中无法使用问题
问题: 解决方法: 在 使用 ueditor 的页面顶部加入js代码: window.UEDITOR_HOME_URL = "__STATIC__/path/to/ueditor/&quo ...