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. POJ1734 - Sightseeing trip

    DescriptionThere is a travel agency in Adelton town on Zanzibar island. It has decided to offer its ...

  2. hdu 4190

    二分求箱子中的票数  然后判是否满足条件     主要为了纪念一下用优先队列9000ms水过 #include<cstdio> #include<climits> #inclu ...

  3. C++11多线程教学(二)

    C++11多线程教学II 从我最近发布的C++11线程教学文章里,我们已经知道C++11线程写法与POSIX的pthreads写法相比,更为简洁.只需很少几个简单概念,我们就能搭建相当复杂的处理图片程 ...

  4. Win32 DLL和MFC DLL 中封装对话框

    现在最常看见的关于DLL的问题就是如何在DLL中使用对话框,这是一个很普遍的关于如何在DLL中使用资源的问题.这里我们从Win32   DLL和MFC   DLL两个方面来分析并解决这个问题.     ...

  5. POJ3096Surprising Strings(map)

    题意:输入很多字符串,以星号结束.判断每个字符串是不是“Surprising Strings”,判断方法是:以“ZGBG”为例,“0-pairs”是ZG,GB,BG,这三个子串不相同,所以是“0-un ...

  6. CF 369 B. Valera and Contest

    http://codeforces.com/contest/369/problem/B 题意 :n, k, l, r, sall, sk,n代表的是n个人,这n个人的总分是sall,每个人的得分大于 ...

  7. What is the innovator’s solution——什么才是创新的解决方案2

    前略:http://www.cnblogs.com/Kassadin/p/4233497.html 案例1 从书上的一个案例开始: 让我们来看看AT&T公司(美国电话电报公司)的案例吧.198 ...

  8. eclipse实现JavaWeb应用增量打包

    很多情况下,项目是不允许全量发布的,所以你得把有做修改的文件一个个挑出来,如果有成千上百的文件,你是不是要头大了? 以下方法应该可以让你得到解救!前提是你是用装有svn plugin的eclipse上 ...

  9. libevent学习之二:Windows7(Win7)下编译libevent

    Linux下编译参考源码中的README文件即可,这里主要记录Windows下的编译. 一.准备工作 去官网下载最新的稳定发布版本libevent-2.0.22-stable 官网地址:http:// ...

  10. P117、面试题18:树的子结构

    题目:输入两棵二叉树A和B,判断B是不是A的子结构.二叉树结点的定义如下:struct BinaryTreeNode{       int  m_nValue;       BinaryTreeNod ...