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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

动态规划训练25 [Food Delivery ZOJ - 3469 ]好题

發布時間:2023/12/3 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划训练25 [Food Delivery ZOJ - 3469 ]好题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Food Delivery

? ZOJ - 3469?

區間DP的一道好題。

在這道題里,無非就是從出發點向左走到x1再向右走到有y1,再向左走到x2,再向右走到y2.。。。這樣,一直將所有的顧客遍歷完。

顯然,起點這個點是非常特殊的一個點,我們姑且也把它算作一名顧客,那么這名顧客的憤怒值設置為0。

然后定義dp[x][y][0]表示區間遍歷完[x,y]了,并且當前停留在x位置上,將對最終的憤怒值之和造成的貢獻。

定義dp[x][y][1]表示遍歷完區間[x,y],并且當前停留在y位置上,將對最終的憤怒之和造成的貢獻。

從上面我們的討論中可以發現[x,y]一定是包含起始點S的,不然這個區間將沒有意義。

我們可以得到狀態轉移的方程 (我們沒有在這里就把V乘進去,而是在最后才把V考慮進去)

dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (Ns[i+1].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (Ns[j].x - Ns[j-1].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));

以上的狀態轉移方程就相當于把區間擴大了一位數字,貢獻增加的值。

我看很多題解的時候,沒有明確說明dp表示的是對于答案的貢獻值,所以沒能充分的理解。

反思這個動態規劃的題目,有點特別,就是說dp代表的東西不能形成一個類似的獨立的子問題,而仍然是刻畫原問題的某個性質的一部分,這里我覺得是與其他一些dp不同的地方。


#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; int N,V,X; const int INF = 1e9; const int MAX = 1005; struct node{int x,val;friend bool operator<(node n1,node n2){return n1.x < n2.x;} }Ns[MAX]; int dp[MAX][MAX][2]; int sum[MAX]; int main(){while(~scanf("%d%d%d",&N,&V,&X)){memset(dp,0,sizeof(dp));for(int i = 1;i <= N;i++){int x,b;scanf("%d%d",&x,&b);Ns[i].x = x;Ns[i].val = b;}Ns[N+1].x = X;Ns[N+1].val = 0;sort(Ns+1,Ns+N+2);int s = 0;while(Ns[++s].x != X);for(int i = 1;i <= N+1;i++) sum[i] = sum[i-1] + Ns[i].val;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;}}dp[s][s][0] = dp[s][s][1] = 0;for(int i = s;i > 0;i--){for(int j = s;j<= N+1;j++){if(i == j) continue;dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (Ns[i+1].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (Ns[j].x - Ns[j-1].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));}}int ans = min(dp[1][N+1][0],dp[1][N+1][1]);printf("%d\n",ans*V);}return 0; }

總結

以上是生活随笔為你收集整理的动态规划训练25 [Food Delivery ZOJ - 3469 ]好题的全部內容,希望文章能夠幫你解決所遇到的問題。

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