传送门

解题思路:

  贪心的想,贪婪值越大的孩子应该分得更多的饼干,那么先sort一遍在此基础上进行dp。最直观的方向,可以设dp[i][j]为前i个孩子一共分得j块饼干的怨恨最小值。然后转移第i+1个孩子的状态,设a[i]为比第i个孩子拿到更多饼干的孩子的个数,这时会出现两种情况:

  1.第i+1个孩子获得的饼干比第i个孩子少,那么a[i+1]=i

  2.第i+1个孩子获得了跟第i个孩子一样多的饼干,那么我们还要找i前面有多少个和i获得同样多的饼干的孩子个数,然后再求出a[i+1]

显而易见第二种情况会大大增加时间复杂度,那么先画个图找找出路

从图上的红框可以看出所有的孩子每人删掉同样多的饼干结果不变。那么获得一条状态转移:dp[i][j]=min(dp[i][j],dp[i][j-i])

同样从上一张图看,若第i个孩子得到了一块饼干,可以通过枚举他前面第k个孩子同样得到1个饼干,得到第二个的状态转移:

   dp[i][j]=min(dp[i][j],dp[k][j-(i-k)]+k*(i到i-k的贪婪值之和))

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3+;
struct node
{
int a,id;
}q[];
bool cmp(node a,node b)
{
return a.a>b.a;
}
long long dp[][maxn];
struct no
{
int i,j;
}g[][maxn];
long long sum[],ans[],r;int n,m;
void print(int i,int j)
{
if(i==) return;
print(g[i][j].i,g[i][j].j);
if(g[i][j].i==i)for(int h=;h<=i;h++)ans[q[h].id]++;
else for(int h=g[i][j].i+;h<=i;h++)ans[q[h].id]=;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&q[i].a),q[i].id=i;
memset(dp,0x3f,sizeof dp);
dp[][]=;
sort(q+,q++n,cmp);
for(int i=;i<=n;i++) sum[i]=sum[i-]+q[i].a;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(j-i>=&&dp[i][j]>dp[i][j-i]){
dp[i][j]=dp[i][j-i];
g[i][j].i=i;g[i][j].j=j-i;
}
for(int k=;k<i;k++){
if(j-(i-k)>=&&dp[i][j]>dp[k][j-(i-k)]+1LL*k*(sum[i]-sum[k])){
dp[i][j]=dp[k][j-(i-k)]+k*(sum[i]-sum[k]);
g[i][j].i=k;g[i][j].j=j-(i-k);
}
}
}
}
cout<<dp[n][m]<<endl;
print(n,m);
for(int i=;i<=n;i++)
printf("%d%c",ans[i],i==n?'\n':' ');
}

CH5105 Cookies (线性dp)的更多相关文章

  1. CH5105 Cookies[线性DP]

    http://contest-hunter.org:83/contest/0x50%E3%80%8C%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E3%80%8D%E4%B ...

  2. $CH5105\ Cookies$ 线性$DP+$贪心

    CH 是很有趣的一道题 : ) Sol 第一反应就是f[i][j]表示前i个小朋友分j块饼干的最小怨气值 但是一个孩子所产生的怨气值并不固定,它与其他孩子获得饼干的情况有关 这里可以用到一个贪心,就是 ...

  3. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  4. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  5. hdu1712 线性dp

    //Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...

  6. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  7. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

  8. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

  9. nyoj44 子串和 线性DP

    线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...

  10. 『最大M子段和 线性DP』

    最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...

随机推荐

  1. 正则匹配电话号码demo

    public static String doFilterTelnum(String sParam) { String result = sParam; if (sParam.length() < ...

  2. 奇思妙想-java实现另类的pipeline模式

    磕叨 在公司做项目是见到前辈们写的一端任务链的代码,大概如下 Runnable task = new TaskA(new TaskB(new TaskC(new taskD()))); task.ru ...

  3. Uniapp使用GoEasy实现websocket实时通讯

    Uniapp作为近来最火的移动端开发技术,一套代码,可以打包成Android/iOS app和各种平台的小程序,可谓是没有最方便只有更方便. GoEasy上架DCloud Uniapp插件市场已经有一 ...

  4. ijkplayer中遇到的问题汇总

    在做音频播放的时候,很多公司使用的是开源的ijkplayer播放器,ijkplayer底层是基于ffmpeg,在某机型上面可能常常遇到各种问题.今天整理了大家在使用ijkplayer中遇到的问题,以及 ...

  5. Linux下安装Python3.4

    PS:如果本机安装了python2,尽量不要管他,使用python3运行python脚本就好,因为可能有程序依赖目前的python2环境, 比如yum!!!!! 不要动现有的python2环境! 1. ...

  6. rest_framework序列化,反序列化

    序列化组件 from rest_framework.response import Response1.Response本质也是继承了httpresponse,比httpResponse还强大,传入一 ...

  7. tarjan算法强连通分量的正确性解释+错误更新方法的解释!!!+hdu1269

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269 以下内容为原创,转载请声明. 强连通分量SCC(Strongly Connected Compo ...

  8. nmap端口扫描工具安装和使用方法

    nmap(Network Mapper)是一款开源免费的针对大型网络的端口扫描工具,nmap可以检测目标主机是否在线.主机端口开放情况.检测主机运行的服务类型及版本信息.检测操作系统与设备类型等信息. ...

  9. PHP Curl进行Post时指定 multipart/form-data 或 application/x-www-form-urlencoded 的方法

    PHP Curl进行Post时指定 multipart/form-data 或 application/x-www-form-urlencoded 的方法 先看一段典型的CURL POST的代码: $ ...

  10. C++实现秒表

    完整代码下载 思路概括:如果有键按下,判断按下的是什么键并处理.没有键按下,计时.传统的Sleep无法满足秒表精确到百毫秒的需求,这里使用更精确的clock,clock的作用是统计从程序开始运行到现在 ...