HDU 6024(中国大学生程序设计竞赛女生专场1002)
这是CCPC女生专场的一道dp题。大佬们都说它简单,我并没有感到它有多简单。
先说一下题意:在一条直线上,有n个教室,现在我要在这些教室里从左到右地建设一些作为糖果屋,每个教室都有自己的坐标xi 和建造糖果屋的费用ci ,
如果在这里建造一个糖果屋,那么花费ci ,如果不建造糖果屋,则花费是当前教室的坐标与左边最靠近当前教室的糖果屋坐标之差,问最小花费。
一看这是个求最优解的问题,应该明白这是个dp问题,现在来考虑该问题状态的定义:
当我建设到第i个教室的时候,我有两种选择,建糖果屋或者不建糖果屋,影响我决策的是在左边离我最近的糖果屋的位置。并且我在建设前i个教室的时候,明显可以看出有i种相互独立的不同方案,即:
将离i最近的且在左边糖果屋建在 1号,2号,3号,......,k号,......,i号教室,所有的方案都可以分成这i类。我想知道建设前i个教室的最小费用,我只需挑出这i种方案中花费最小的那个就行。
并且,在我后面继续建设的时候,我一定还会用到这i种方案做基础,比如说我要建设第i+1个房间了,将最近的糖果屋建设在1~i已经有了现成的方案供我们选择,我们额外需要考虑的只是将糖果屋
建设在第i+1间教室时的情况。
于是我们定义状态dp[i][j]---->现在已经建设到第i个教室了,离i最近且在左边的的教室号为j时,我们能求得的最小花费。
状态转移方程:
if(i == j) dp[i][j] = minn[i - 1] + ci;
else dp[i][j] = dp[i - 1][j] + (xi - xj);
其中minn[k]指的是建设前k间教室的最小花费。
显然,当我们把最近的糖果屋建设在i号教室时,我们需要建设前i - 1间教室的最优解 + 建 i 号教室的费用,才能保证当前状态的最优解的生成。
这个minn[k]是可以顺带着算出来的,详见代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define maxn 3005
#define F 0x7f
#define INF 0x3f3f3f3f3f3f3f
using namespace std;
struct room
{
long long x,c;
};
room store[maxn];
long long dp[][maxn];
long long minn[maxn];
const long long zero = ;
bool cmp(const room& a,const room& b)
{
return a.x < b.x;
}
int main()
{
int n;
while(scanf("%d",&n) == ){
for(int i = ;i <= n;++i) dp[][i] = INF;
for(int i = ;i <= n;++i) dp[][i] = ;
for(int i = ;i <= n;++i) minn[i] = INF;
for(int i = ;i <= n;++i) scanf("%lld%lld",&store[i].x,&store[i].c);
sort(store + ,store + n + ,cmp);
dp[][] = store[].c;
minn[] = dp[][];
for(int i = ;i <= n;++i){
for(int j = ;j <= i;++j){
if(i == j) dp[i & ][j] = minn[i - ] + store[i].c;
else dp[i & ][j] = dp[(i - ) & ][j] + (store[i].x - store[j].x);
minn[i] = min(minn[i],dp[i & ][j]);
}
}
printf("%lld\n",minn[n]);
}
return ;
}
这里有一个特别坑的地方:标号小的教室坐标未必小,即这些教室不一定是从左到右标号的。
同时为了减少内存开销,我采用了滚动数组。
HDU 6024(中国大学生程序设计竞赛女生专场1002)的更多相关文章
- 2017中国大学生程序设计竞赛 - 女生专场 1002 dp
Building Shops Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- 2017中国大学生程序设计竞赛 - 女生专场(dp)
Building Shops Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- 2017中国大学生程序设计竞赛 - 女生专场 Deleting Edges(思维+最短路)
Deleting Edges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- 2017中国大学生程序设计竞赛 - 女生专场 Happy Necklace(递推+矩阵快速幂)
Happy Necklace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- 2017中国大学生程序设计竞赛 - 女生专场(Graph Theory)
Graph Theory Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- 2017中国大学生程序设计竞赛 - 女生专场B【DP】
B HDU - 6024 [题意]:n个教室,选一些教室建造糖果商店. 每个教室,有一个坐标xi和在这个教室建造糖果商店的花费ci. 对于每一个教室,如果这个教室建造糖果商店,花费就是ci,否则就是与 ...
- hdu_5705_Clock("巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5705 题意:给你一个时间和一个角度,问你下一个时针和分针形成给出的角度是什么时候 题解:我们可以将这个 ...
- hdu_5707_Combine String("巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5707 题意:给你三个字符串 a,b,c,问你 c能否拆成a,b,a,b串的每一个字符在c中不能变 题解 ...
- 2017中国大学生程序设计竞赛 - 女生专场C【前后缀GCD】
C HDU - 6025 [题意]:去除数列中的一个数字,使去除后的数列中所有数字的gcd尽可能大. [分析]: 数组prefixgcd[],对于prefixgcd[i]=g,g为a[0]-a[i]的 ...
随机推荐
- 老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 4
这一部分的代码逻辑关系是这样的: 344行: 一个外部循环每次从上次保存下来的设备列表获得一个设备Device实例 350行: 再在一个内部循环从最新的设备列表中获得一个设备Device实例 353行 ...
- 测试开发Python培训:抓取新浪微博评论提取目标数据-技术篇
测试开发Python培训:抓取新浪微博评论提取目标数据-技术篇 在前面我分享了几个新浪微博的自动化脚本的实现,下面我们继续实现新的需求,功能需求如下: 1,登陆微博 2,抓取评论页内容3,用正则表 ...
- 细细探究MySQL Group Replicaiton — 配置维护故障处理全集
本文主要描述 MySQL Group Replication的简易原理.搭建过程以及故障维护管理内容.由于是新技术,未在生产环境使用过,本文均是虚拟机测试,可能存在考虑不周跟思路有误 ...
- Springboot在IDEA中执行,开启热部署
仅适用IDEA中,eclipse中不需要设置 一.开启idea自动make功能 1 - Enable Automake from the compiler PRESS: CTRL + SHIFT + ...
- Entity Framework Code First在Oracle下的伪实现
为什么要说是伪实现,因为还做不到类似MsSql中那样完全的功能.Oralce中的数据库还是要我们自己手动去创建的.这里,我们舍掉了Model First中的EDMX文件,自己在代码里面写模型与映射关系 ...
- 2017携程Web前端实习生招聘笔试题总结
考察encodeURI encodeURI(), decodeURI()它们都是Global对象的方法. encodeURI()通过将某些字符的每个实例替换代表字符的UTF-8编码的一个或多个转义字符 ...
- javascript的getter和setter(转)
显然这是一个无关IE(高级IE除外)的话题,尽管如此,有兴趣的同学还是一起来认识一下ECMAScript5标准中getter和setter的实现.在一个对象中,操作其中的属性或方法,通常运用最多的就是 ...
- linux(ubuntu)获取命令源码方式
以下载ls的源码为例说明: 首先要知道ls是属于哪个包的,可以通过下面命令: #dpkg -S 'command name' 通用格式 $ dpkg -S /bin/ls 得到如下结果: coreut ...
- git的使用及常用命令(二)
一,把文件放在版本库中 执行 git add XXX文件名 在执行 git commit -m ‘提交注释' 查看状态 git status 如果没有改变文件,nothing to comment ...
- 从源码角度入手实现RecyclerView的Item点击事件
RecyclerView 作为 ListView 和 GridView 的替代产物,相信在Android界已广为流传. RecyclerView 本是不会有类似 ListView 的那种点击事件,但是 ...