前言

模板一套就AC了...

题目

guardians.cpp 1S/128M

你负责将监狱的警卫指派到最疯狂的罪犯所在的监狱。 一共有N间牢房排列成一行,编号从1~N。 第i间牢房恰好容纳了一个疯狂程度为C[i]的罪犯。

每个罪犯都应该有一个警卫监视他/她。 理想情况下,应该让一名警卫监视一个罪犯。 然而,由于预算限制,你只能分配G个警卫。 为了最大程度地降低有人逃脱的总风险,你必须指定每个警卫应该监视哪些罪犯。当然,你应该将每个警卫分配给一组相邻的牢房。
第i个罪犯可能逃脱的风险R[i]由下式给出:
R[i] = C[i] * 指派监视他的警卫监视的罪犯数量
请你分配一个最佳的方案,使所有罪犯的风险之和最小。

输入
第1行:2个整数N和G (1 <= N <= 8000, 1 <= G <= 800)
第2行:N个整数,表示C[i] ( 1 <= C[i] <= 10^9)

输出
第1行:1个整数,表示答案

Sample Input
6 3
11
11
11
24
26
100

Sample Output
299

Explain
第1个警卫监视1~3,第2个警卫监视4~5,第3个警卫监视6

分析

详细的关于该优化的讲解我有写博客:决策单调性分治优化

经观察可以发现本题基本模型为:分组+花费最小

可以写出DP定义与转移方程:

dp[ i ][ j ]:1~j个犯人被第i个狱长监管

对于最后一个狱长i,假设从第k到j的犯人被最后第i狱长监管

dp[ i ][ j ]=min( dp[ i ][ j ],dp[ i-1 ][ k-1 ]+( s[ j ] - s[ k ] ) * ( j - k + 1 ) ) ;

s[ i ]:1~i的前缀和

初始化:dp[ 1 ][ 1~n ]=INF

然后直接套用【决策单调性分治优化】或【四边形不等式优化】即可,详见代码

决策单调性分治优化-代码(含暴力DP)

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=8000,MAXG=800;
#define INF (1LL << 60)
ll c[MAXN+5],s[MAXN+5],dp[MAXG+5][MAXN+5];
ll n,g;
void DP(ll d,ll i,ll j,ll optl,ll optr)//决策优化
{if(i>j)return ;ll mid=(i+j)/2;ll opt=INF,id;//暴力计算二分点的dp值opt与最小决策点id for(int k=optl;k<=min(mid,optr);k++){ll cur=dp[d-1][k-1]+(mid-k+1)*(s[mid]-s[k-1]);if(cur<opt)opt=cur,id=k;}dp[d][mid]=opt;//递归求解决策点左右两部分的dp值 DP(d,i,mid-1,optl,id);DP(d,mid+1,j,id,optr);
}
void Solve1()
{for(int i=1;i<=n;i++)dp[0][i]=INF;for(int i=1;i<=g;i++)DP(i,1,n,1,n);printf("%lld\n",dp[g][n]);
}
void Solve2()//普通DP(没调出来,奇怪)
{/*dp[i][j]:1~j个犯人被第i个狱长监管对于最后一个狱长i,假设从第k到j的犯人被最后第i狱长监管 dp[i][j]=min(dp[i][j],dp[i-1][k-1]+(s[j]-s[k])*(j-k+1)); */for(int i=1;i<=n;i++)dp[1][i]=INF;//dp[0][0]=0;for(int i=1;i<=g;i++)for(int j=1;j<=n;j++)for(int k=1;k<=j;k++){//printf("(%d,%d):%lld\n",i,j,dp[i][j]);dp[i][j]=min(dp[i][j],dp[i-1][k-1]+(j-k+1)*(s[j]-s[k-1]));//printf(" %lld\n",dp[i][j]);}printf("%lld\n",dp[g][n]);
}
int main()
{//freopen("guardians.in","r",stdin);//freopen("guardians.out","w",stdout);scanf("%lld%lld",&n,&g);for(int i=1;i<=n;i++){scanf("%lld",&c[i]);s[i]=s[i-1]+c[i];}Solve1();//Solve2();return 0;
} 

四边形不等式优化-代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=8000,MAXG=800;
#define INF (1LL<<60)
ll c[MAXN+5],s[MAXN+5],dp[MAXG+5][MAXN+5];
ll n,g;
void Solve()
{for(int i=0;i<=g;i++)for(int j=0;j<=n;j++)dp[i][j]=INF;dp[0][0]=0;for(int i=1;i<=g;i++){ll opt=0;for(int j=i;j<=n;j++)for(int k=opt;k<=j;k++){ll tmp=1ll*(j-k+1)*(s[j]-s[k-1]);if(dp[i-1][k-1]+tmp<=dp[i][j])dp[i][j]=dp[i-1][k-1]+tmp,opt=k;}}/*打表验证单调性 for(int i=1;i<=n;i++)for(int j=i;j<=n;j++){w[i][j]=(j-i+1)*(s[j]-s[i-1]);//printf("%d %d %lld\n",i,j,w[i][j]);}for(int a=1;a<=n;a++)for(int b=a+1;b<=n;b++)for(int c=b+1;c<=n;c++)for(int d=c+1;d<=n;d++)printf("%d %d %d %d %lld %lld\n",a,b,c,d,w[a][c]+w[b][d],w[a][d]+w[b][c]);*/printf("%lld\n",dp[g][n]);
}
int main()
{scanf("%lld%lld",&n,&g);for(int i=1;i<=n;i++){scanf("%lld",&c[i]);s[i]=s[i-1]+c[i];}Solve();return 0;
}

【决策单调性分治优化/四边形不等式优化】监狱警卫相关推荐

  1. BZOJXXXX: [IOI2000]邮局——四边形不等式优化初探

    貌似$BZOJ$上并没有这个题... 是嫌这个题水了么... 还是要氪金权限号??? 这里附上洛谷的题面:洛谷P4767 [IOI2000]邮局 题目描述 高速公路旁边有一些村庄.高速公路表示为整数轴 ...

  2. [转]四边形不等式优化dp(POJ1160)

    四边形不等式优化动态规划原理: 1.当决策代价函数w[i][j]满足w[i][j]+w[i'][j']<=w[I;][j]+w[i][j'](i<=i'<=j<=j')时,称w ...

  3. 四边形不等式优化-石子合并

    四边形不等式优化 四边形不等式定义 在oi历程中,常有如下的dp转移方程 \(f(i,j)=min(f(i,k)+f(k+1,j)+w(i,j))\) \((i<=k<j)\) \(f(i ...

  4. 四边形不等式优化 --算法竞赛专题解析(10)

    本系列文章将于2021年整理出版,书名<算法竞赛专题解析>. 前驱教材:<算法竞赛入门到进阶> 清华大学出版社 2019.8 网购:京东 当当      作者签名书 如有建议, ...

  5. Post Office(邮局)之四边形不等式优化dp

    目录 前言 题目 解析 四边形不等式优化 何为四边形不等式 何为区间包含单调性 四边形不等式性质 DP 优化 参考代码(附注释) 前言 可以说这道题我可花费了很大功夫才理解的. 其中有些小技巧也是我钻 ...

  6. Codevs 3002 石子归并 3(DP四边形不等式优化)

    3002 石子归并 3 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次 ...

  7. 合并石子 四边形不等式优化

    题目描述 有一排石子,共n 堆.现要将石子有次序地合并成一堆.规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.试设计一个算法,计算出将n堆石子合并成一堆的最小得分. ...

  8. DP 最优二叉树 的四边形不等式优化

    最优比例二叉树.代价函数cost 满足 对任意 a <= b <= c <= d 有 cost[a,c] + cost[b,d] <= cost[a,d] + cost[b,c ...

  9. 【HDU 4905 多校联合】The Little Devil II【DP+四边形不等式优化】

    题意:给出一个数列,每次你可以选择相邻的两个数字进行求GCD,然后得到的数字把这两个数字替代,得到GCD的权值,求最后剩下一个数字后的最大的权值(权值初始是数列的和) 思路:定义dp[i][j]表示区 ...

最新文章

  1. Qt Dll总结——链接库预备知识(转载)
  2. 只要你的AI算法能比小白鼠聪明,DeepMind的这20万奖金请拿走
  3. 千位分隔符的完整攻略
  4. wifi信号手机测试软件,专业的WiFi检测工具有哪些?如何解决wifi信号不好?
  5. JS编程建议——32:使用制表
  6. SPOJ1716 GSS3(线段树)
  7. B站举办2021年度百大UP主盛典 科技知识类UP主占比翻倍
  8. qt调用外部程序(exe)
  9. mac memcached_如何在Mac OS上安装Memcached Server
  10. 【读书笔记《Android游戏编程之从零开始》】15.游戏开发基础(剪切区域)
  11. git可视化工具小乌龟安装使用
  12. Android GPS学习笔记—HAL实现
  13. uni-app 小程序引入字体图标
  14. 投资组合理论的简单介绍
  15. “神一般存在”的印度理工学院到底有多牛?
  16. 互联网时代创业推荐三本书
  17. 苹果4s怎么越狱_这次是真的!iPhone成功刷入安卓系统,苹果急了......
  18. 华为鸿蒙麒麟巴龙鲲鹏,华为四大芯片 麒麟、巴龙、昇腾和鲲鹏“四大天王”...
  19. 【NVMe2.0b 2】NVMe 结构理论
  20. 你拥有的最宝贵的财富是什么?(通向财富自由学习笔记三)

热门文章

  1. codevs1051
  2. Python sum() TypeError: ‘int‘ object is not callable xxxxxxxxx XXXXXXXXXX
  3. 连锁不平衡的计算方法
  4. 全国行政区划代码(json对象版)
  5. 海之心预约登记系统 独立版 稳定更新 疫情防控出入登记访客登记安保巡查维修表单预约自定义小区厂区公司核酸检测
  6. Halcon版权费、hdevelop和hdevelop xl的区别
  7. C# Json压缩和格式化
  8. 用手机如何查看当地的2g信号强度
  9. matlab怎么求解多元非线性方程组,利用MATLAB如何求解如下非线性方程组,
  10. Linux 系统忘记 root 用户密码(重置)