日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVA1336 Fixing the Great Wall 洛谷P2466 [SDOI2008]Sue的小球【区间DP记忆化搜索】

發布時間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVA1336 Fixing the Great Wall 洛谷P2466 [SDOI2008]Sue的小球【区间DP记忆化搜索】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

UVA1336 Fixing the Great Wall

Time limit 3000ms


題目大意

長城上有N個地點要修補,給定每個點的位置、初始修復成本,每單位時間增加的成本
給定修補機器人 初始位置及移動速度
求機器人如何移動使得總成本最小


題目分析

將這N個點按位置排序
顯然如果一個點走過他再回頭修一定不會最優
所以任意時刻已修補的區間一定是連續的
即若當前以修好第llllll~rrrrrr個地點,那么下一個修補的一定是ll?1ll-1ll?1rr+1rr+1rr+1

定義dp[ll][rr][0/1]dp[ll][rr][0/1]dp[ll][rr][0/1]表示已經修好了[ll,rr][ll,rr][ll,rr]區間的地點,且當前所在位置為ll(0)ll(0)ll(0)還是rr(1)rr(1)rr(1)
修補完剩下的地點所需最小化費

初始化dp[1][n][0]=dp[1][n][1]=0dp[1][n][0]=dp[1][n][1]=0dp[1][n][0]=dp[1][n][1]=0,其余為INF
狀態轉移方程
W=Sum[n]?(Sum[rr]?Sum[ll?1])W=Sum[n]-(Sum[rr]-Sum[ll-1])W=Sum[n]?(Sum[rr]?Sum[ll?1])及計算剩余沒修補的地點每單位時間增加的成本總和
dp[ll][rr][0]=min(dp[ll?1][rr][0]+Len(ll?1,ll)/V?W,dp[ll][rr+1][1]+Len(ll,r+1)/V?W)dp[ll][rr][0]=min(dp[ll-1][rr][0]+Len(ll-1,ll)/V*W,dp[ll][rr+1][1]+Len(ll,r+1)/V*W)dp[ll][rr][0]=min(dp[ll?1][rr][0]+Len(ll?1,ll)/V?W,dp[ll][rr+1][1]+Len(ll,r+1)/V?W)
dp[ll][rr][1]=min(dp[ll?1][rr][0]+Len(ll?1,rr)/V?W,dp[ll][rr+1][1]+Len(rr,r+1)/V?W)dp[ll][rr][1]=min(dp[ll-1][rr][0]+Len(ll-1,rr)/V*W,dp[ll][rr+1][1]+Len(rr,r+1)/V*W)dp[ll][rr][1]=min(dp[ll?1][rr][0]+Len(ll?1,rr)/V?W,dp[ll][rr+1][1]+Len(rr,r+1)/V?W)

注意這里我們還要把機器人的初始位置作為一個點加進去,所以總點數應為N+1
設排序后表示機器人的點為K,從DP(k,k,0)開始記搜即可
答案為dp[k][k][0]+SUMdp[k][k][0]+SUMdp[k][k][0]+SUM (SUM為初始成本總和)


#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<algorithm> #include<cstring> using namespace std; typedef double dd;int read() {int f=1,x=0;char ss=getchar();while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}return f*x; }const int inf=1e9; const int maxn=1010; int n,v,x; struct node{dd pos,c,dt;}rem[maxn]; bool cmp(node a,node b){return a.pos<b.pos;} dd sum[maxn],dp[maxn][maxn][2];dd DP(int ll,int rr,int d) {if(ll==1&&rr==n+1) return 0;if(dp[ll][rr][d]!=inf) return dp[ll][rr][d];dd resl=0,resr=0,ss=sum[n+1]-(sum[rr]-sum[ll-1]);if(ll>1){if(d==1) resl=(rem[rr].pos-rem[ll-1].pos)/v*ss;else resl=(rem[ll].pos-rem[ll-1].pos)/v*ss;}if(rr<=n){if(d==1) resr=(rem[rr+1].pos-rem[rr].pos)/v*ss;else resr=(rem[rr+1].pos-rem[ll].pos)/v*ss;}if(ll>1) dp[ll][rr][d]=min(dp[ll][rr][d],DP(ll-1,rr,0)+resl);if(rr<=n) dp[ll][rr][d]=min(dp[ll][rr][d],DP(ll,rr+1,1)+resr);return dp[ll][rr][d]; }int main() {while(scanf("%d%d%d",&n,&v,&x)!=EOF){if(n==0&&v==0&&x==0) break; dd ssum=0;for(int i=1;i<=n;++i)scanf("%lf%lf%lf",&rem[i].pos,&rem[i].c,&rem[i].dt);rem[n+1].pos=x; rem[n+1].c=0; rem[n+1].dt=0;//將機器人也作為一個點加入sort(rem+1,rem+2+n,cmp);for(int i=1;i<=n+1;++i)ssum+=rem[i].c,sum[i]=sum[i-1]+rem[i].dt;for(int i=1;i<=n+1;++i)for(int j=1;j<=n+1;++j)dp[i][j][0]=dp[i][j][1]=inf;for(int i=1;i<=n+1;++i)if(rem[i].pos==x){ printf("%.0lf\n",floor(DP(i,i,0)+ssum)); break;}}return 0; }

洛谷P2466 [SDOI2008]Sue的小球

時空限制 1000ms / 128MB

題目描述

Sue和Sandy最近迷上了一個電腦游戲,這個游戲的故事發在美麗神秘并且充滿刺激的大海上,Sue有一支輕便小巧的小船。然而,Sue的目標并不是當一個海盜,而是要收集空中漂浮的彩蛋,Sue有一個秘密武器,只要她將小船劃到一個彩蛋的正下方,然后使用秘密武器便可以在瞬間收集到這個彩蛋。然而,彩蛋有一個魅力值,這個魅力值會隨著彩蛋在空中降落的時間而降低,Sue要想得到更多的分數,必須盡量在魅力值高的時候收集這個彩蛋,而如果一個彩蛋掉入海中,它的魅力值將會變成一個負數,但這并不影響Sue的興趣,因為每一個彩蛋都是不同的,Sue希望收集到所有的彩蛋。

然而Sandy就沒有Sue那么浪漫了,Sandy希望得到盡可能多的分數,為了解決這個問題,他先將這個游戲抽象成了如下模型:

以Sue的初始位置所在水平面作為x軸。

一開始空中有N個彩蛋,對于第i個彩蛋,他的初始位置用整數坐標(xi, yi)表示,游戲開始后,它勻速沿y軸負方向下落,速度為vi單位距離/單位時間。Sue的初始位置為(x0, 0),Sue可以沿x軸的正方向或負方向移動,Sue的移動速度是1單位距離/單位時間,使用秘密武器得到一個彩蛋是瞬間的,得分為當前彩蛋的y坐標的千分之一。

現在,Sue和Sandy請你來幫忙,為了滿足Sue和Sandy各自的目標,你決定在收集到所有彩蛋的基礎上,得到的分數最高。

輸入格式:

第一行為兩個整數N, x0用一個空格分隔,表示彩蛋個數與Sue的初始位置。
第二行為N個整數xi,每兩個數用一個空格分隔,第i個數表示第i個彩蛋的初始橫坐標。
第三行為N個整數yi,每兩個數用一個空格分隔,第i個數表示第i個彩蛋的初始縱坐標。
第四行為N個整數vi,每兩個數用一個空格分隔,第i個數表示第i個彩蛋勻速沿y軸負方向下落的的速度。

輸出格式:

一個實數,保留三位小數,為收集所有彩蛋的基礎上,可以得到最高的分數。

說明

對于30%的數據,N<=20。
對于60%的數據,N<=100。
對于100%的數據,?104&lt;=xi,yi,vi&lt;=104,N&lt;=1000-10^4 &lt;= xi,yi,vi &lt;= 10^4,N &lt; = 1000?104<=xi,yi,vi<=104N<=1000


題目分析

和上面一樣的題型
每個彩蛋iii的得分看作 初始從坐標yi?y_i-yi??下落距離
為了讓這個得分盡可能的大,轉換一下就是要讓下落距離盡量小

令SUM為初始所有縱坐標總和sum[i]sum[i]sum[i]記錄viv_ivi?前綴和
dp[ll][rr][0/1]dp[ll][rr][0/1]dp[ll][rr][0/1]表示已經取得了第llllll~rrrrrr的彩蛋且當前在llllll還是rrrrrr,要取完剩下區間能得到的最小下落距離

和上面的轉移如出一轍
記得把初始位置也作為一個點加進去xixixi升序排序后記搜即可
最后ans=(SUM?DP(K,K,0))/1000ans=(SUM-DP(K,K,0))/1000ans=(SUM?DP(K,K,0))/1000


#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<cmath> using namespace std; typedef long long lt; typedef double dd;int read() {int x=0,f=1;char ss=getchar();while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}return x*f; }const int inf=1128481603; const int maxn=1010; int n,x0,SUM; struct node{ int xi,yi,vi,f; node(){xi=yi=vi=f=0;}}rem[maxn]; bool cmp(node a,node b){return a.xi<b.xi;} int sum[maxn],dp[maxn][maxn][2];int DP(int ll,int rr,int d) {if(ll==1&&rr==n) return 0;if(dp[ll][rr][d]!=inf) return dp[ll][rr][d];int res=inf,resl=0,resr=0,ss=sum[n]-(sum[rr]-sum[ll-1]);if(ll>1){if(d==1) resl=(rem[rr].xi-rem[ll-1].xi)*ss;else resl=(rem[ll].xi-rem[ll-1].xi)*ss;}if(rr<n){if(d==1) resr=(rem[rr+1].xi-rem[rr].xi)*ss;else resr=(rem[rr+1].xi-rem[ll].xi)*ss; }if(ll>1) res=min(res,resl+DP(ll-1,rr,0));if(rr<n) res=min(res,resr+DP(ll,rr+1,1));return dp[ll][rr][d]=res; }int main() {n=read(); x0=read();for(int i=1;i<=n;++i) rem[i].xi=read();for(int i=1;i<=n;++i) rem[i].yi=read();for(int i=1;i<=n;++i) rem[i].vi=read();rem[++n].xi=x0; rem[n].yi=0; rem[n].vi=0; rem[n].f=1;memset(dp,67,sizeof(dp));sort(rem+1,rem+n+1,cmp);for(int i=1;i<=n;++i) sum[i]=sum[i-1]+rem[i].vi,SUM+=rem[i].yi;for(int i=1;i<=n;++i)if(rem[i].f==1){ printf("%.3lf",(dd)(SUM-DP(i,i,1))/1000.0); break;}return 0; }

總結

以上是生活随笔為你收集整理的UVA1336 Fixing the Great Wall 洛谷P2466 [SDOI2008]Sue的小球【区间DP记忆化搜索】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。