5105 Cookies 0x50「动态规划」例题

描述

圣诞老人共有M个饼干,准备全部分给N个孩子。每个孩子有一个贪婪度,第 i 个孩子的贪婪度为 g[i]。如果有 a[i] 个孩子拿到的饼干数比第 i 个孩子多,那么第 i 个孩子会产生 g[i]*a[i]的怨气。给定N、M和序列g,圣诞老人请你帮他安排一种分配方式,使得每个孩子至少分到一块饼干,并且所有孩子的怨气总和最小。1≤N≤30, N≤M≤5000, 1<=gi<=10^7。

输入格式

第一行两个整数N,M,第二行N个整数g1~gN。

输出格式

第一行一个整数表示答案,第二行N个整数表示每个孩子分到的饼干数。本题有SPJ,若有多种方案,输出任意一种均可。

样例输入

样例输入1
3 20
1 2 3 样例输入2
4 9
2 1 5 8

样例输出

样例输出1
2
2 9 9 样例输出2
7
​2 1 3 3

来源

ITMO

题意:给n个小孩分m颗糖,如果有x个小孩的糖比第i个小孩多的话,那么不满意度就会是g[i]*x

问总不满意度最小的分糖方式

思路:贪婪度越大的小孩拿到的糖应该要尽量多,因为要使得尽量少的小孩糖数比他多

所以先按照贪婪度从大到小排个序,他们拿到的糖果数是非递增的

用“已获得饼干的孩子数”和“已发放的饼干数”作为DP的阶段

dp[i, j]表示前i个孩子一共分配j块饼干时,怨气总和的最小值

那么第i+1个小孩有两种情况:1.他拿到的比第i个小孩少,则比他糖果多的有i个人

2.他拿到的和第i个小孩一样多,此时需要找到前i个中,和第i个一样多的小孩的个数

需要用等效的方法

当我们发现第i个小孩的饼干数大于1时,我们就给前面每个小孩的饼干数减1,也就是说dp[i][j] = dp[i][j - i]。因为每个人都减1,相对的大小是不变的

当第i个小孩的饼干数等于1时,就枚举i前面有多少小孩也是1块饼干。此时d[i][j] = dp[i][j - (i - k)] + k * g[p](p = k+1~i)。假设有k个小孩不是1.

求最小的dp[n][m]即可,因为要输出方案,所以每次需要存一下

a[i][j] = i说明是第一种情况,否则是第二种情况。b数组用来回溯

虐狗宝典笔记:

有时可以通过额外的算法确定DP状态的计算顺序,有时可以在状态空间中运用等效手法对状态进行缩放。

本题中我们利用贪心,在DP前进行排序,使获得的饼干数单调递减

还利用相对大小的不变性,把第i+1个孩子获得的饼干数缩放到1,再考虑i前面有几个孩子获得的饼干数量相等

#include <bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<map> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; int n, m;
const int maxn = , maxm = ;
struct node{
int g, id;
}child[maxn];
int dp[maxn][maxm], sum[maxn];
int a[maxn][maxm], b[maxn][maxm], ans[maxn]; bool cmp(node a, node b)
{
return a.g > b.g;
} void print(int n, int m)
{
if(n == )return ;
print(a[n][m], b[n][m]);
if(a[n][m] == n){
for(int i = ; i <= n; i++)ans[child[i].id]++;
}
else{
for(int i = a[n][m] + ; i <= n; i++)ans[child[i].id] = ;
}
} int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++){
scanf("%d", &child[i].g);
child[i].id = i;
}
memset(dp, inf, sizeof(dp));
sort(child + , child + + n, cmp); dp[][] = ;
for(int i = ; i <= n; i++){
sum[i] = sum[i - ] + child[i].g;
for(int j = i; j <= m; j++){
int tmp = inf;
dp[i][j] = dp[i][j - i];
a[i][j] = i;
b[i][j] = j - i;
for(int k = ; k < i; k++){
if(dp[k][j - i + k] + k * (sum[i] - sum[k]) < dp[i][j]){
dp[i][j] = dp[k][j - i + k] + k * (sum[i] - sum[k]);
a[i][j] = k;
b[i][j] = j - i + k;
}
}
}
}
printf("%d\n", dp[n][m]);
print(n, m);
printf("%d", ans[]);
for(int i = ; i <= n; i++){
printf(" %d", ans[i]);
}
printf("\n");
return ;
}

CH5105 Cookies【贪心】【线性dp】的更多相关文章

  1. CH5105 Cookies (线性dp)

    传送门 解题思路: 贪心的想,贪婪值越大的孩子应该分得更多的饼干,那么先sort一遍在此基础上进行dp.最直观的方向,可以设dp[i][j]为前i个孩子一共分得j块饼干的怨恨最小值.然后转移第i+1个 ...

  2. CH5105 Cookies饼干(线性DP)

    题意理解 圣诞老人共有\(M\)个饼干,准备全部分给\(N\)个孩子. 每个孩子有一个贪婪度,第 i 个孩子的贪婪度为 \(g[i]\). 如果有 \(a[i]\) 个孩子拿到的饼干数比第 \(i\) ...

  3. 【CH5105】cookies 贪心+DP

    通过邻项交换法可知,怨气值大的孩子分得的饼干数也应该多(否则交换之后得到的解更优). 观察目标函数的性质,可知目标函数本身是由孩子饼干数的相对大小得到,因此此题中关注的是相对大小. 状态设计:\(dp ...

  4. 动态规划_线性dp

    https://www.cnblogs.com/31415926535x/p/10415694.html 线性dp是很基础的一种动态规划,,经典题和他的变种有很多,比如两个串的LCS,LIS,最大子序 ...

  5. DP基础(线性DP)总结

    DP基础(线性DP)总结 前言:虽然确实有点基础......但凡事得脚踏实地地做,基础不牢,地动山摇,,,嗯! LIS(最长上升子序列) dp方程:dp[i]=max{dp[j]+1,a[j]< ...

  6. 非常完整的线性DP及记忆化搜索讲义

    基础概念 我们之前的课程当中接触了最基础的动态规划. 动态规划最重要的就是找到一个状态和状态转移方程. 除此之外,动态规划问题分析中还有一些重要性质,如:重叠子问题.最优子结构.无后效性等. 最优子结 ...

  7. 线性DP 学习笔记

    前言:线性DP是DP中最基础的.趁着这次复习认真学一下,打好基础. ------------------ 一·几点建议 1.明确状态的定义 比如:$f[i]$的意义是已经处理了前$i个元素,还是处理第 ...

  8. 贪心/构造/DP 杂题选做

    本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...

  9. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  10. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

随机推荐

  1. atitit.loading的设计与实现控件选型attilax 总结

    atitit.loading的设计与实现控件选型attilax 总结 1. Percentage Loader(推荐) 1 1.1. 起始百分比::调整  progress 1 2. CSS3 Loa ...

  2. Virtex6 PCIe 超简版基础概念学习(二)

    Virtex6 PCIe 超简版基础概念学习(二) 分类:FPGAPCIe (2081)  (0)  举报  收藏 文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 ise14.7 ...

  3. 如何在iOS上实现对HTTPS的支持(转)

    原文地址:http://blog.5ibc.net/p/101504.html 首先,需要明确你使用HTTP/HTTPS的用途,因为OSX和iOS平台提供了多种API,来支持不同的用途,官方文档< ...

  4. lua工具库penlight--07函数编程(二)

    列表压缩 列表压缩是以紧凑的方式通过指定的元素创建表.在 Python里,你可以说: ls = [x for x in range(5)]  # == [0,1,2,3,4] 在 Lua,使用pl.c ...

  5. org.apache.hadoop.hbase.DoNotRetryIOException: Class org.apache.phoenix.coprocessor.MetaDataEndpointImpl cannot be loaded Set hbase.table.sanity.checks to false at conf or table descriptor if you want

    https://stackoverflow.com/questions/38495331/apache-phoenix-unable-to-connect-to-hbase 这个坑不该啊 首选配置hb ...

  6. php -- 魔术方法 之 序列化和反序列化的触发函数:__sleep(),__wakeup()

    __sleep():当对象被当做文件保存时会自动触发的方法. 该方法要做的事情,就是返回一个要保存的对象数据的数组 DB.class.php中修改 再次保存效果 读取db对象 因为没有连接数据,不能操 ...

  7. 【UVa】And Then There Was One(dp)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  8. 转载:Python十分钟入门

    Python十分钟入门:http://python.jobbole.com/23425/

  9. SQL操作【整理中...】

    /////////////////////////////////////////////////////////////////////////////////////////////////数据库 ...

  10. sublime window 配置记录 (转)

    大家好,今天给大家分享一款编辑器:sublime text2    我用过很多编辑器,EditPlus.EmEditor.Notepad++.Notepad2.UltraEdit.Editra.Vim ...