Uva1336 修长城 【有关未来费用的区间dp】
2017-07-05 16:08
429 查看
题外话
此题简化版:codevs1258/洛谷P1220此题(伪)升级版:送披萨(可以选择送给这个人或者不送)
题目大意中的题目背景属于报复行为,大家无视即可。
题目大意
邪恶的魔王jyf用厉害的膜法在长城上制造了n个破坏点,正义的守护者boshi此时正处于x处,他急忙准备去修复长城。对于每个破坏点,boshi站在这个破坏点前面,然后用修复膜法瞬间修复,但是需要花费一些体力,并且由于jyf的膜法狠厉害,所以每过1s,破坏就会增大,所以实际上boshi在第ts修复点i的花费体力为ci+t*di,而boshi开着小电驴的移动速度为v。由于boshi很懒,他不想花太多体力,所以请你帮他求出他修好长城要花多少体力?题目分析
首先,对于一段连续的区间[l,r],boshi是如此的大佬以至于他不会走出这个区间修几个点然后再溜达回来修完,所以boshi每一步修的区间一定是连续的,那么boshi在修完这个区间后,他要么在区间最左端,要么在最右端,那么我们可以用f(l,r,t)表示boshi修[l,r]区间的花费体力,其中当t=1时boshi在最右端,否则在最左端。那么当boshi在最左端的时候,他肯定已经修复了[l+1,r]这个区间,修复这个区间后是在左还是在右就是决策,然后花费便是boshi从[l+1,r]这个区间走到l位置的时间里,所有没修复的(不在区间[l+1,r]中的)破坏点的t*di值的增大值。在最右端同理。
用记忆化搜索解决。
注意l==r的情况。
代码
#include<cstdio> #include<iostream> #include<cstring> #include<climits> #include<cmath> #include<algorithm> using namespace std; int n;double v,u; struct node{double x,c,d;}p[1005]; double f[1005][1005][2],sum[1005]; bool cmp(node a,node b){return a.x<b.x;} double dp(int l,int r,int t){//0:在左边,1:在右边 if(f[l][r][t]!=-1)return f[l][r][t]; if(l==r){ f[l][r][t]=fabs(u-p[l].x)/v*sum +p[l].c; return f[l][r][t]; } if(!t){ double tot=sum -sum[r]+sum[l]; f[l][r][t]=dp(l+1,r,0)+tot*(p[l+1].x-p[l].x)/v+p[l].c; f[l][r][t]=min(f[l][r][t],dp(l+1,r,1)+tot*(p[r].x-p[l].x)/v+p[l].c); } else { double tot=sum -sum[r-1]+sum[l-1]; f[l][r][t]=dp(l,r-1,1)+tot*(p[r].x-p[r-1].x)/v+p[r].c; f[l][r][t]=min(f[l][r][t],dp(l,r-1,0)+tot*(p[r].x-p[l].x)/v+p[r].c); } return f[l][r][t]; } int main() { int i,j,k;double c; while(scanf("%d%lf%lf",&n,&v,&u)==3&&n){ for(i=1;i<=n;i++)scanf("%lf%lf%lf",&p[i].x,&p[i].c,&p[i].d); n++;p .x=u;p .c=p .d=0; sort(p+1,p+1+n,cmp); for(i=1;i<=n;i++)sum[i]=sum[i-1]+p[i].d; for(i=1;i<=n;i++)for(j=i;j<=n;j++)f[i][j][1]=f[i][j][0]=-1; printf("%.0lf\n",floor(min(dp(1,n,1),dp(1,n,0)))); } return 0; }
相关文章推荐
- 区间DP(修缮长城,uva 1336)
- UVA1628 送匹萨 [有关未来费用的区间dp (伪)升级版]
- UVA-1336 Fixing the Great Wall(区间DP)
- Fixing the Great Wall UVA - 1336(区间dp+前缀和)
- UVa 1336 Fixing the Great Wall (区间DP)
- UVA - 1336(考虑未来费用)
- UVA 1336 Fixing the Great Wall(区间DP)
- uva 10003 一根木棍上有n个切割点 4000 每次选一个点切割,求总切割费用最小 区间DP
- 【UVa 10003】【区间DP】Cutting Sticks【有一个长为L的木棍,木棍中间有n个切点。每次切割的费用为当前木棍的长度。求切割木棍的最小费用。】
- uva 10453 - Make Palindrome (区间dp,记忆化搜索)
- uva 10304 Optimal Binary Search Tree(区间dp)
- UVA 字符串区间DP
- POJ 1141 / UVa 1626 Brackets Sequence (区间DP&打印路径)
- UVALive 3363 String Compression (区间DP,4级)
- UVALIVE4394,区间DP好题
- UVA 1626 - Brackets sequence 区间DP
- uva 10304 Optimal Binary Search Tree (区间DP)
- uva 10891 Game of Sum(区间dp)
- Uva 10891 Game of Sum - 区间DP..记忆化搜索
- uva10003 - Cutting Sticks(DP,区间)