2017中国大学生程序设计竞赛 - 女生专场B【DP】
【题意】:n个教室,选一些教室建造糖果商店。 每个教室,有一个坐标xi和在这个教室建造糖果商店的花费ci。 对于每一个教室,如果这个教室建造糖果商店,花费就是ci,否则就是与坐标在自己前面的建造糖果商店的距离, 求最小花费。
【分析】:
题解1.首先最左面的楼是必须要建商店的。考虑dp,dp[i][j]表示在第i栋楼是否建商店的最小花费(0不建,1建)。
j==1:则dp[i][1]=min(dp[i-1][1],dp[i-1][0]) + 建商店花费;
j==0:则我们找到左面建商店的楼 j,dp[i][0]=dp[j][1] +(j +1至i 楼到 j 栋的花费)。注意位置不是按升序给的,要排个序。
题解2.根据题目所给的时间,和题目的数据的大小,我们可以知道题目可以承受住时间复杂度为O(n^2)。
并且每个教室只有两种方案,要么建超市,要么不建。这就很像是背包问题了,所以我们就想到了dp.
我们设dp[i][0]表示在教室i不建超市时前i个教室的费用和的最小值;dp[i][1]表示在教室i建超市时前i个教室的费用和的最小值
那么我们很快可以得出:
dp[i][1] = min(dp[i-1][0],dp[i-1][1]) + ci
dp[i][0],由于可以承受住时间复杂度为O(n^2)的算法,那么我们就可以想到枚举离教室 i 最近的超市 j 的位置,然后取所有情况的最小值就可以了。
假设左边最近超市为 j ,那么教室 j+1 ~教室i 都不能建超市,所以教室 j+1~教室i 的费用分别为他们的位置到教室j 之间的距离了。
dp[i][0] = dp[j][1] + ( 教室j+1~教室i 的费用 )
如果我们暴力求解,那么时间复杂度会变成O(n^3),会超时。但是我们会发现由于j是从大到小变化的,所以就可以用:t += (i - j) * (nodes[j+1].x - nodes[j].x);来记录教室j+1~教室i的费用和了。
关于 t += (i - j) * (nodes[j+1].x - nodes[j].x); 的解释:
比如我们要算x3 - x1 , x2 - x1的sum,那么由于保证了x是升序排列的,所以sum = (x3 - x2) + 2 * (x2 - x1).
【代码】:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include <vector>
#include<iostream>
using namespace std;
#define N 50005
#define INF 0x3f3f3f3f
#define LL long long
LL dp[N][];
struct node
{
LL x,c;
}s[N];
int cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=;i<=n;i++)
scanf("%lld %lld",&s[i].x,&s[i].c);
sort(s+,s+n+,cmp);
memset(dp,,sizeof(dp));
dp[][] = s[].c;///东边肯定有糖果店 所以第一个教室是必须建糖果店的
dp[][] = INF;
for(int i=;i<=n;i++)
{
dp[i][] = min(dp[i-][],dp[i-][])+s[i].c;
///在这个教室建立糖果店所需要的最小花费
LL sum=;
dp[i][] = INF;
///找到前面花费最小的糖果店
for(int j=i-;j>=;j--)
{
sum+=(i-j)*(s[j+].x-s[j].x);
dp[i][] = min(dp[i][],dp[j][]+sum);
}
}
printf("%lld\n",min(dp[n][],dp[n][]));
///取建糖果店与不建糖果店的其中的小值
}
return ;
}
还很鶸阿
2017中国大学生程序设计竞赛 - 女生专场B【DP】的更多相关文章
- 2017中国大学生程序设计竞赛 - 女生专场(dp)
Building Shops Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- 2017中国大学生程序设计竞赛 - 女生专场 1002 dp
Building Shops Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- 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中国大学生程序设计竞赛 - 女生专场C【前后缀GCD】
C HDU - 6025 [题意]:去除数列中的一个数字,使去除后的数列中所有数字的gcd尽可能大. [分析]: 数组prefixgcd[],对于prefixgcd[i]=g,g为a[0]-a[i]的 ...
- 2017中国大学生程序设计竞赛 - 女生专场A【模拟】
A HDU - 6023 [题意]:求AC题数和总时长. [分析]:模拟.设置标记数组记录AC与否,再设置错题数组记录错的次数.罚时罚在该题上,该题没AC则不计入总时间,AC则计入.已经AC的题不用再 ...
- HDU 6024(中国大学生程序设计竞赛女生专场1002)
这是CCPC女生专场的一道dp题.大佬们都说它简单,我并没有感到它有多简单. 先说一下题意:在一条直线上,有n个教室,现在我要在这些教室里从左到右地建设一些作为糖果屋,每个教室都有自己的坐标xi 和建 ...
- "巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场
Combine String #include<cstdio> #include<cstring> #include<iostream> #include<a ...
随机推荐
- ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
A.Arcade Game(康拓展开) 题意: 给出一个每个数位都不同的数n,进行一场游戏.每次游戏将n个数的每个数位重组.如果重组后的数比原来的数大则继续游戏,否则算输.如果重组后的数是最大的数则算 ...
- [51nod1791] 合法括号子段 DP
---题面--- 题解: 首先我们需要发现一个性质,在括号序列不变的情况下,括号匹配是不会变的,因此不论子串怎么取,括号匹配的关系是不会变化的.这是一个很容易发现的性质,然而我太弱,没发现. 于是可以 ...
- Flink 任务打包、提交
一.Flink版本 flink-1.6.1-bin-hadoop26-scala_2.11 二.Flink任务打包 笔者将写好的flink计算任务代码发到服务器(ubuntu16.04),在服务器端进 ...
- [NOI2010]能量采集 解题报告
[NOI2010]能量采集 题目描述 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. ...
- AnnotationConfigApplicationContext.的用法的核心代码
public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationCont ...
- PRINT_TABLE 列以行形式显示
在sqlplus,如果列比较多,往往会显示不够清晰,这时如果能把查询语句行转列就明了多了,在网上看到print_table存储过程:里面所设置的日期格式,可根据自己习惯修改 CREATE OR REP ...
- AngularJs学习——实现数据绑定的三种方式
三种方式: 方式一:<h5>{{msg}}</h5> 此方式在页面刷新的时候会闪现{{}} 方式二:<h5 ng-bind="msg">< ...
- 【Codeforces】849D. Rooter's Song
[算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...
- 【比赛】百度之星2017 初赛Round B
第一题 题意:给定n*m网络,定义两个棋子在同行同列则相互攻击,同时要求两个棋子的行和列不能一小一大,求满足条件的最大摆放的方案数. 题解:ans=C(max(n,m),min(n,m)),就是在ma ...
- Nodejs写的搬家工具知识分享
这篇文章 主要学习这两个模块的使用: request-promise-native : https://github.com/request/request-promise-native cheeri ...