CH 5105 Cookies(贪心+DP)
$ CH 5105 Cookies $
$ solution: $
真是好题一道!这道题我想了很久很久,就得这一题可以直接完全贪心,可惜最后还是失败了,但是对贪心的深入思考也换来了一个最优解方案。然后这一题的DP也考的很有技术!
贪心1:这一道题当时第一眼就是贪心。首先不管每一个孩子的贪婪度,只要我们将糖果分为 $ N $ 份,实际上就已经确定了会存在多少个孩子他们的糖果数比多少个其他孩子要少。于是我们贪心的让贪婪度小的孩子去做那些糖果数比多少个其他孩子要少的孩子。(虽然这在伦理上说不过去)
贪心2,它可以减少数据范围:如果某些孩子的糖果数一样那么他们彼此之间就不会产生怨气。所以当我们将糖果平均分时,产生的怨气最少(就是没有怨气)。但是我们的糖果数不一定就能平均分了,但是我们依旧可以贪心的让相同糖果数的人尽量多。其次我们可以想到:如果糖果不够平均分,那么一定存在几个人他们的糖果数比其他所有人都低!这样我们就能产生一个很自然的想法:先平均分,如果还剩下几个不够让所有的孩子在多拿一个糖果,就钦定从贪婪度嘴小的孩子里拿回糖果给其他的孩子使得除了这个孩子以外其他孩子都是平均分的(真的好不公平啊),这样肯定能最优。但是我们同样不能保证把这个孩子的所有糖果都拿回能使得(除了这个孩子以外其他孩子都是平均分的)。但是这种情况在 $ m>n^2 $ 的时候可以得到保证,多以我们可以将 $ m $ 限制在 $ n^2 $ 以内,于是数据范围就被我们消减了,然后博主就拿到了CH上的最优解。。。。。。
然后讲一下DP,这道题的DP比较难想,因为我们首先需要想到第一个贪心,然后我们发现贪婪度小的孩子分的糖果少,于是我们按照贪婪度从大到小排序,这就符合我们线性DP的要求了。我完全可以设 $ F[i][j] $ 表示前 $ i $ 个孩子用了 $ j $ 颗糖果。但是这一题DP也难快速转移,我们如果正常转移花费的时间很多,会超时(如果我们用第二个贪心减少数据范围,也可以跑过去)。于是我们需要优化,这时候我们发现由于后面的孩子因为贪婪度小分到的糖果少一些,于是我们可以转移一下:假如第 $ i+1 $ 个孩子比第 $ i $ 个孩子得到的糖果少一个,那么这就相当于前 $ i $ 个孩子都多拿了一个糖果(这两个想法是等效的)。于是转移方程变成了:
$ F[i][j]={{F[i][j-i]}_{{ min}_{0\leq k<i}{F[k][j-(i-k)]+k\times (S[i]-S[k]) }}} $
注: $ S[i] $ 表示前 $ i $ 个孩子的贪婪度总和。
$ code: $
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int
using namespace std;
int n,m;
int S[35];
int as[35];
int f[35][905];
struct su{
int da,id;
inline bool operator <(const su &x)const{return da>x.da;}
}a[35];
struct pi{
int x,y;
}d[35][905];
inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
}
inline void tepan(){
printf("%d\n",a[n].da*(n-1));
rg ans=m/n,res=m%n;
for(rg i=1;i<n;++i) as[a[i].id]=ans+bool(res);
as[a[n].id]=ans; if(res) as[a[n].id]-=n-res-1;
for(rg i=1;i<=n;++i) printf("%d ",as[i]);
puts(""); exit(0);
}
inline void print(int i,int j){
if(i==0)return ;
else print(d[i][j].x,d[i][j].y);
if(d[i][j].x==i) for(rg k=1;k<=i;++k)++as[a[k].id];
else for(rg k=d[i][j].x+1;k<=i;++k)++as[a[k].id];
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=qr(); m=qr();
for(rg i=1;i<=n;++i)
a[i].da=qr(),a[i].id=i;
sort(a+1,a+n+1); if(m>n*n)tepan();
for(rg i=1;i<=n;++i) S[i]=S[i-1]+a[i].da;
for(rg i=1;i<=m;++i) f[0][i]=1e9;
for(rg i=1;i<=n;++i){
for(rg j=0;j<=m;++j){
if(j<i){f[i][j]=1e9; continue;}
f[i][j]=f[i][j-i]; d[i][j].x=i; d[i][j].y=j-i;
for(rg k=0;k<i;++k){
rg tot=f[k][j-(i-k)]+k*(S[i]-S[k]);
if(tot<f[i][j])f[i][j]=tot,d[i][j].x=k,d[i][j].y=j-(i-k);
}
}
} printf("%d\n",f[n][m]); print(n,m);
for(rg i=1;i<=n;++i) printf("%d ",as[i]);
puts(""); return 0;
}
CH 5105 Cookies(贪心+DP)的更多相关文章
- 【CH5105】cookies 贪心+DP
通过邻项交换法可知,怨气值大的孩子分得的饼干数也应该多(否则交换之后得到的解更优). 观察目标函数的性质,可知目标函数本身是由孩子饼干数的相对大小得到,因此此题中关注的是相对大小. 状态设计:\(dp ...
- 【BZOJ-3174】拯救小矮人 贪心 + DP
3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 686 Solved: 357[Submit][Status ...
- 洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp
正解:贪心+dp 解题报告: 传送门! 我以前好像碰到过这题的说,,,有可能是做过类似的题qwq? 首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得 ...
- 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人
P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...
- BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP
BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...
- 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp
题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...
- 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp
题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...
- hdu 1257 最少拦截系统【贪心 || DP——LIS】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- 贪心+dp
贪心+dp 好多题都是这个思想, 可以说是非常重要了 思想一: 在不确定序列无法dp的情况下, 我们不妨先假设序列已经选定, 而利用贪心使序列达到最优解, 从而先进行贪心排序, 在进行dp选出序列 思 ...
随机推荐
- ACM程序设计选修课——1081: 堆(BFS)
1081: 堆 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 26 Solved: 9 Description Input Output Sampl ...
- HDU——4549M斐波那契数列(矩阵快速幂+快速幂+费马小定理)
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Su ...
- 刷题总结——瞭望塔(bzoj1038)
题目: Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线 ...
- 将一个list均分成n个list
/** * 将一个list均分成n个list,主要通过偏移量来实现的 * @param source * @return */ public <T> List<List<T&g ...
- phoenixframework集成了所有自动化测试的思想的平台。mark一下。
phoenixframework http://www.cewan.la/
- Codevs 1043 ==洛谷 P1004 方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- Java面试题集(五)
三.开源框架 什么是mybaties? Mybaties是支持普通sql查询,存储过程和高级映射的优秀持久层框架.Mybaties消除了几乎所有的jdbc代码和参数的手工设置以及结果集的检索.Myba ...
- ROS节点分布式运行方法
一. 主机Master设置 1.安装ssh客服端和服务器(ubuntu已默认安装了) 2.机器名与ip绑定 由于/etc/hosts中需要将计算机名和IP绑定,所有最好设置IP地址为静态地址 sudo ...
- sqlite 常用操作
#查看当前数据库信息 .database #列出所有表 .tables #列出所有字段 .schema 或者 .schema table_name #清空一张表 delete from tabl ...
- Chrome查看同步状态
最近Hosts不太稳定,翻出去之后安装了一些插件,那么会面临一些问题,比如插件是否已经同步成功,其它PC能否获取等等. 下面是一些查询同步状态的入口: https://www.google.com/s ...