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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

SP703 SERVICE - Mobile Service[DP]

發布時間:2023/11/29 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SP703 SERVICE - Mobile Service[DP] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意翻譯

Description   一個公司有三個移動服務員。如果某個地方有一個請求,某個員工必須趕到那個地方去(那個地方沒有其他員工),某一時刻只有一個員工能移動。只有被請求后,他才能移動,不允許在同樣的位置出現兩個員工。從位置P到Q移動一個員工的費用是C(P, Q)。這個函數沒有必要對稱,但是C(P, P) = 0。一開始三個服務員分別在位置1,2,3,公司必須滿足所有的請求。 目標是最小化公司的費用。 Input   第1行:2個整數L,N(3<=L<=200, 1<=N<=1000). L是位置數,每個位置從1到L編號,N是請求數。   接下來L行,每行包含L個非負整數,第i+1行的第j個數表示C(i, j),并且它小于2000.   最后一行包含N個數,是請求列表。 Output    第1行:一個數M,表示最小的服務花費

輸入輸出樣例

輸入樣例#1:?
1 5 9 0 1 1 1 1 1 0 2 3 2 1 1 0 4 1 2 1 5 0 1 4 2 3 4 0 4 2 4 1 5 4 3 2 1 輸出樣例#1:?
5
解析:

這題值得好好理解。是我滾動數組入門題目。

容易想到以當前的請求作為階段,當前服務員所在位置的最小花費作為狀態。
首先,
四維數組會爆空間。不用滾動數組也會爆空間。。。

我們假設dp[i][x][y]表示在第i個請求時,有一個服務員在x位置,一個服務員在y位置。如果x和y都不在上一個請求所在位置,那么剩下那個服務員必定在上一個請求的位置那里。

我們有三種決策:
  • 將上一個請求位置的服務員轉移到當前請求的位置上,前提是x和y都不在上一個請求所在位置;
  • 將x處的服務員轉移到當前請求的位置上,前提是y處的服務員不在當前請求的位置上(注意:上一個請求位置上的服務員不可能在此處了,不需要此條件);
  • 將y處的服務員轉移到當前請求的位置上,前提是x處的服務員不在當前請求的位置上;

我們很容易設計狀態轉移方程:

if(x!=p[i]&&y!=p[i])dp[now][x][y]=min(dp[now][x][y],dp[now^1][x][y]+a[p[i-1]][p[i]]); if(y!=p[i])dp[now][p[i-1]][y]=min(dp[now][p[i-1]][y],dp[now^1][x][y]+a[x][p[i]]); if(x!=p[i])dp[now][x][p[i-1]]=min(dp[now][x][p[i-1]],dp[now^1][x][y]+a[y][p[i]]);

當然,這些方程都有一個大前提,就是當前請求的x和y既不能在同一個位置上,又不能在上一個請求的位置上(注意細節)。

最后,我們檢查一遍最后一個請求時的狀態,找出最小值就OK了。

?

參考代碼:

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<string> 7 #include<cstdlib> 8 #include<queue> 9 #include<vector> 10 #define INF 0x3f3f3f3f 11 #define PI acos(-1.0) 12 #define N 201 13 #define MOD 2520 14 #define E 1e-12 15 #define ri register int 16 using namespace std; 17 int a[N][N],dp[2][N][N],p[1001]; 18 inline int read() 19 { 20 int f=1,x=0;char c=getchar(); 21 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 22 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 23 return x*f; 24 } 25 int main() 26 { 27 int t; 28 cin>>t; 29 while(t--) 30 { 31 memset(a,0,sizeof(a)); 32 memset(p,0,sizeof(p)); 33 int now=0,l,n; 34 l=read(),n=read(); 35 for(ri i=1;i<=l;i++) 36 for(ri j=1;j<=l;j++) a[i][j]=read(); 37 for(ri i=1;i<=n;i++) p[i]=read(); 38 memset(dp[now],0x3f,sizeof(dp)); 39 p[0]=3;dp[0][1][2]=0; 40 for(ri i=1;i<=n;i++){ 41 now^=1;//滾動數組 42 memset(dp[now],0x3f,sizeof(dp[now])); 43 for(ri x=1;x<=l;x++)//有l個地方可以去 44 if(x!=p[i-1]) 45 for(ri y=1;y<=l;y++) 46 { 47 if(x==y&&y==p[i-1]) continue; 48 if(x!=p[i]&&y!=p[i]) 49 dp[now][x][y]=min(dp[now][x][y],dp[now^1][x][y]+a[p[i-1]][p[i]]); 50 if(y!=p[i]) 51 dp[now][p[i-1]][y]=min(dp[now][p[i-1]][y],dp[now^1][x][y]+a[x][p[i]]); 52 if(x!=p[i]) 53 dp[now][x][p[i-1]]=min(dp[now][x][p[i-1]],dp[now^1][x][y]+a[y][p[i]]); 54 } 55 } 56 int ans=INF; 57 for(ri i=1;i<=l;i++) 58 for(ri j=1;j<=l;j++) 59 if(i!=j&&i!=p[n]&&j!=p[n]) 60 ans=min(ans,dp[now][i][j]);//另一個人在p[n]處 61 cout<<ans<<endl; 62 } 63 return 0; 64 }

?

轉載于:https://www.cnblogs.com/DarkValkyrie/p/11053352.html

總結

以上是生活随笔為你收集整理的SP703 SERVICE - Mobile Service[DP]的全部內容,希望文章能夠幫你解決所遇到的問題。

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