最小总代价(洛谷-U17433)
題目描述
n個人在做傳遞物品的游戲,編號為1-n。
游戲規則是這樣的:開始時物品可以在任意一人手上,他可把物品傳遞給其他人中的任意一位;下一個人可以傳遞給未接過物品的任意一人。
即物品只能經過同一個人一次,而且每次傳遞過程都有一個代價;不同的人傳給不同的人的代價值之間沒有聯系;
求當物品經過所有n個人后,整個過程的總代價是多少。
輸入輸出格式
輸入格式:
第一行為n,表示共有n個人(16>=n>=2);
以下為n*n的矩陣,第i+1行、第j列表示物品從編號為i的人傳遞到編號為j的人所花費的代價,特別的有第i+1行、第i列為-1(因為物品不能自己傳給自己),其他數據均為正整數(<=10000)。
輸出格式:
一個數,為最小的代價總和。
輸入輸出樣例
輸入樣例#1:
2
-1 9794
2724 –1
輸出樣例#1:
2724
思路:狀壓 DP 入門題
每個人只能被傳遞一次,用一個 n 位二進制數來表示每個人是否被訪問過,但這無法知道物品在誰手中,因此加一個狀態,來表示物品在誰手中。
用 f[i][j] 表示在 i 狀態時最后的一個是 j,初始狀態為 f[1<<i][i]=0;表示一開始物品在i手中,所求狀態為 min(f[(1<<n)-1][j]);? 因此有轉移方程:f[i][j]=min(f[i-(1<<j)][k]+cost[k][j],f[i][j])?
k 表示從 k 點轉移到了 j 位置,所以要求 j、k 都應該是集合 i 中的元素
源代碼
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<cstdlib> #include<queue> #include<set> #include<map> #include<stack> #include<ctime> #include<vector> #define INF 0x3f3f3f3f #define PI acos(-1.0) #define N 1001 #define MOD 10007 #define E 1e-6 #define LL long long using namespace std; LL f[1<<17][20],cost[20][20]; int main() {int n;cin>>n;for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>cost[i][j];/*標識狀態初始化*/memset(f,127,sizeof(f));for(int i=0;i<n;i++)f[1<<i][i]=0;int cnt=(1<<n)-1;for(int i=1;i<=cnt;i++){for(int j=0;j<n;j++){if(i&(1<<j)){for(int k=0;k<n;k++){if( j!=k && (i&(1<<k)) )//k在狀態i中不存在{LL x=(i-(1<<j));f[i][j]=min(f[x][k]+cost[k][j],f[i][j]);}}}}}LL minn=INF;for(int i=0;i<n;i++)minn=min(minn,f[cnt][i]);cout<<minn<<endl;return 0; }?
總結
以上是生活随笔為你收集整理的最小总代价(洛谷-U17433)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 括弧匹配检验(信息学奥赛一本通-T135
- 下一篇: Lake Counting(信息学奥赛一