UVa 10618 Fixing the Great Wall

题目:

 http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36139

思路:

  数轴上有n个点需要修复,每个点有信息c,x,d 表示位于x且在t时修缮的费用是c+d*t,找一个修缮序列使n个点能全部修缮且有费用最小。

可以发现:在任意时刻,修缮完的点都是连续的,因为修缮不需要时间,将一些点“顺手”修缮了肯定不差。

d[i][j][k],表示已经将i-j个点修缮完后位于p(if (k==0) p=i;else p=j;)的花费,不知道时间怎么办呢?

:注意到每个点的花费是c+d*t ,累计花费并不一定要将每个点的花费都求出来然后相加。于是正式定义d表示该清情况下所有已知花费,每当因为移动时间耗去t所有没有访问的点u花费都会相应增加u.d*t,总花费增加sum_d*t。换句话说,这种方法根据花费的特点将单个点花费累加变成了累计未访问点在未访问时间内的花费。

当位于ijk时有两种抉择:左走i-1 j 0 或右走 i j+1 1 这就是子问题 。

答案不大于10^9 但过程中好像input中会出现超int的情况但long long空间占用太大,因此用了double,最后转成int。

代码:

 #include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<(c);a++)
using namespace std; const int maxn = + ;
const int INF = 1e30; struct Node{
double x,c,d;
bool operator <(const Node& rhs) const {
return x<rhs.x; }
};
Node nodes[maxn]; int n,kase;
double v,x,d[maxn][maxn][];
//d记录目前已知的所有花费
double pre_d[maxn];
int vis[maxn][maxn][]; inline double cost(double x,double y,int i,int j) {
double finished=;
if(i>j) return 0.0;
if(i>= && j>=) finished += pre_d[j]-pre_d[i-]; //sum_d[i,j]
return (pre_d[n]-finished) * fabs(y-x)/v; //总花费+所有未访问的点.d*t
} double dp(int i,int j,int k) {
if(i== && j==n) return ; // 边界
double& ans=d[i][j][k];
if(vis[i][j][k]==kase) return ans;
vis[i][j][k]=kase; //记忆化搜索 ans=INF;
double x=(k==? nodes[i].x:nodes[j].x);
if(i>) ans=min(ans,dp(i-,j,) + cost(x,nodes[i-].x,i,j));
if(j<n) ans=min(ans,dp(i,j+,) + cost(x,nodes[j+].x,i,j));
return ans;
} int main() {
kase=;
memset(vis,,sizeof(vis));
while(scanf("%d%lf%lf",&n,&v,&x)== && (n&&v&&x)) {
++kase;
double sumc=;
FOR(i,,n+){
scanf("%lf%lf%lf",&nodes[i].x,&nodes[i].c,&nodes[i].d);
sumc += nodes[i].c;
}
sort(nodes+,nodes+n+); pre_d[]=;
FOR(i,,n+) pre_d[i]=pre_d[i-]+nodes[i].d; //'哨兵' 如果初始点在第0个点的左或第n个点的右 //使满足判断的普遍性
nodes[].x=-INF;
nodes[n+].x=INF;
double ans= INF;
FOR(i,,n+)
if(x>nodes[i-].x && x<nodes[i].x){ //找到起点位置处于i-1...i 然后移动向左|右点
if(i>) ans=min(ans,dp(i-,i-,)+cost(x,nodes[i-].x,-,-));
if(i<=n) ans=min(ans,dp(i,i,)+cost(x,nodes[i].x,-,-));
break;
}
printf("%0.lf\n",floor(ans + sumc));
}
return ;
}

【暑假】[深入动态规划]UVa 10618 Fixing the Great Wall的更多相关文章

  1. 【暑假】[深入动态规划]UVa 10618 Fun Game

    UVa 10618 Fun Game 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36035 思路:   一圈人围坐 ...

  2. 【暑假】[深入动态规划]UVa 10618 Tango Tango Insurrection

    UVa 10618 Tango Tango Insurrection 题目: Problem A: Tango Tango Insurrection You are attempting to lea ...

  3. 【暑假】[深入动态规划]UVa 10618 The Bookcase

    UVa 12099  The Bookcase 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=42067 思路:    ...

  4. UVa 1336 Fixing the Great Wall (区间DP)

    题意:给定 n 个结点,表示要修复的点,然后机器人每秒以 v 的速度移动,初始位置在 x,然后修复结点时不花费时间,但是如果有的结点暂时没修复, 那么每秒它的费用都会增加 d,修复要花费 c,坐标是 ...

  5. UVA-1336 Fixing the Great Wall(区间DP)

    题目大意:长城(视作x正半轴)有n处破损.有一个智能修复机器人,它的初始位置和移动速度已知.每处破损处都有一组参数(x,c,d),x表示位置,c.d表示在时间t后再修复该处破损的花费为d*t+c.求用 ...

  6. 【杂题总汇】UVa-1336 Fixing the Great Wall

    [UVA-1336]Fixing the Great Wall 一开始把题看错了……直接用的整数存储答案:之后用double存最后输出答案的时候取整就AC了

  7. 【暑假】[深入动态规划]UVa 1628 Pizza Delivery

    UVa 1628 Pizza Delivery 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51189 思路:    ...

  8. 【暑假】[深入动态规划]UVa 1380 A Scheduling Problem

     UVa 1380 A Scheduling Problem 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41557 ...

  9. 【暑假】[深入动态规划]UVa 12170 Easy Climb

    UVa 12170 Easy Climb 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=24844 思路:  引别人一 ...

随机推荐

  1. 你不需要jQuery(二)

    完全没有否定jQuery的意思,jQuery是一个神奇的.非常有用的工具,可以节省我们大量的时间. 但是,有些时候,我们只需要jQuery的一个小功能,来完成一个小任务,完全没有必要加载整个jQuer ...

  2. eval()字符串转成对象

    var s = "{a:1,b:2}"; console.log(typeof s); s = eval("(" + s + ")"); c ...

  3. uc/os初始化

        操作系统初始化函数OS_INIT是操作系统在开始运行的最初,对全局变量.任务控制块.就绪表.事件及消息队列等重要数据结构进行的初始化操作,并创建空闲任务.统计任务等系统任务.该函数必须在创建用 ...

  4. eclipse中切换jre后报错:Java compiler level does not match the version of the installed Java project facet.

    项目移除原来的jre环境lib后,添加本地的jre,报错如下: Java compiler level does not match the version of the installed Java ...

  5. CrackMe_001

    本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如 ...

  6. robots.txt协议-互联网robots搜索规范

    最近在看搜索爬虫相关的,挺有趣的,记录一些信息备用. robots.txt官方说明网站 http://www.robotstxt.org/ robots.txt原则 Robots协议是国际互联网界通行 ...

  7. pthread_create用法

    linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread. #include <pthread.h> int pthread_create(pth ...

  8. C#日期格式及其运算

    C#日期时间格式化 转载: http://www.cnblogs.com/hantianwei/archive/2010/09/23/1833228.html

  9. poj 3318 Matrix Multiplication 随机化算法

    方法1:暴力法 矩阵乘法+优化可以卡时间过的. 方法2:随机化 随机构造向量x[1..n],则有xAB=xC;这样可以将小运算至O(n^2). 代码如下: #include<iostream&g ...

  10. Android:控件GridView的使用

    如果是列表(单列多行形式)的使用ListView,如果是多行多列网状形式的优先使用GridView. <?xml version="1.0" encoding="u ...