2017.10.27 sue的小球 失败总结

来源:互联网 发布:c语言中arr 编辑:程序博客网 时间:2024/05/16 15:43

这个题是论文题。。。说这个题之前先说一下关路灯

这两个题都有时间的限制,但都不能作为状态设计进去

关路灯那个题,由于要忽略时间的限制,所以对于一个区间省得最多,是不是就是最优解了呢

首先,就算你知道这个区间关完的时间,由于只记录改区间省得最多,可能导致时间花费增大,而时间花费还会对其他区间造成影响,例:



蓝色路径是 9999 - 999的花费最小区间,但他花费了大量的时间,,实际上9999 - 99999999的区间最优值应由一条不是蓝色的路径的9999 - 999区间转移来

所以在dp的每一步时应该把对其他的价值减少的影响也考虑进来


由于关路灯那个题要求的就是这个,所以自然就有了那个题的dp


而这个题它是要你求区间的收益,而不是其他区间的损失,,

所以就需要动态计算收益,,以前做过一个树形dp,也是每一个节点的答案不是子树问题的答案,是根节点答案的一部分

然后把收益计算式拆一下,1/1000可以最后统一除,这样收益就可以量化了,但每个点还有一个基数,所以计算收益时还要把基数加进来


码:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int f[1005][1005][2],i,j,n,x0,l,r,qsum[1005],hsum[1005],w[1005][1005];struct la{int x,v,y;}a[1005];bool cmp(la a,la b){return a.x<b.x;}int main(){scanf("%d%d",&n,&x0);for(i=1;i<=n;i++)scanf("%d",&a[i].x);for(i=1;i<=n;i++)scanf("%d",&a[i].y);for(i=1;i<=n;i++)scanf("%d",&a[i].v);sort(a+1,a+1+n,cmp);a[n+1].x=9999999;l=1;r=n+1;while(l<r){int mid=(l+r)>>1;if(a[mid].x<=x0)l=mid+1;else r=mid;}for(i=n+1;i>l;i--){a[i].x=a[i-1].x;a[i].v=a[i-1].v;a[i].y=a[i-1].y;}a[l].x=x0;a[l].v=0;a[l].y=0;n++;for(i=1;i<=n;i++){qsum[i]=qsum[i-1]+a[i].v;}for(i=n;i>=1;i--){hsum[i]=hsum[i+1]+a[i].v;}for(i=1;i<=n;i++)for(j=i;j<=n;j++)w[i][j]=qsum[i-1]+hsum[j+1],f[i][j][0]=f[i][j][1]=-1000000009;f[l][l][0]=f[l][l][1]=0;for(i=l;i>=1;i--)for(j=l;j<=n;j++){if(i==j)continue;f[i][j][0]=a[i].y+max(f[i+1][j][0]-(a[i+1].x-a[i].x)*w[i+1][j],f[i+1][j][1]-(a[j].x-a[i].x)*w[i+1][j]);   //在左边 f[i][j][1]=a[j].y+max(f[i][j-1][0]-(a[j].x-a[i].x)*w[i][j-1],f[i][j-1][1]-(a[j].x-a[j-1].x)*w[i][j-1]);   //在you边}printf("%.3lf",0.001*max(f[1][n][0],f[1][n][1]));}





阅读全文
0 0
原创粉丝点击