小明目前在做乙份畢業旅行的規劃。打算從北京出發,分別去若干個城市,然後再回到北京,每個城市之間均乘坐高鐵,且每個城市只去一次。由於經費有限,希望能夠通過合理的路線安排盡可能的省一些路上的花銷。給定一組城市和每對城市之間的火車票的價錢,找到每個城市只訪問一次並返回起點的最小車費花銷。
城市個數n(1示例140 2 6 5
2 0 4 4
6 4 0 2
5 4 2 0
13
共 4 個城市,城市 1 和城市 1 的車費為0,城市 1 和城市 2 之間的車費為 2,城市 1 和城市 3 之間的車費為 6,城市 1 和城市 4 之間的車費為 5,依次類推。假設任意兩個城市之間均有單程票可購買,且票價在1000元以內,無需考慮極端情況。思路:這道題我一直卡在起點的選擇上,在一開始,我一度固執的以為起點不同將影響最優解。後來發現其實是無所謂的,舉乙個例子:
假如有5個城市編號分別為0~5,此時已知一條最優解的路徑是:3->2->0->5->4->3,意味著從3出發,再回到3是最優的,我們將路徑拆成兩部分:3->2和2->0->5->4->3。由於路徑是最優的,則我們知道從2走到3一定是最優的路徑(不然不是和最優解矛盾了嘛),而3->2是一條直接路徑,值是固定的,因此我們發現這條環形路徑的起點就是無所謂的, 所以不妨設為0,(其實我確實想複雜了,環形路徑糾結什麼起點啊)。
下面是正確解法:對於旅行商這類np難的問題,在資料量不大的情況下我們可以考慮採用狀態壓縮的方法去列舉所走的城市路線的,例如定義dp[i][j]:表示走到城市並且狀態為j的最短路徑,而這個狀態相信學過狀態壓縮的人一定不難理解,我們將經過的城市表示為二進位制位裡的1,例如:101就表示已經經過了城市0,和城市2,後面就是狀壓dp的轉移了,直接看答案即可(注意記憶體超限問題,有點坑)。
#include#include#include#include#includeusing namespace std;
int n,edges[25][25];
vector> dp;
int main(void)}}
printf("%d\n",dp[0][m-1]);
return 0;
}
位元組跳動歷屆筆試題(1)
有三隻球隊,每只球隊編號分別為球隊1,球隊2,球隊3,這三隻球隊一共需要進行 n 場比賽。現在已經踢完了k場比賽,每場比賽不能打平,踢贏一場比賽得一分,輸了不得分不減分。已知球隊1和球隊2的比分相差d1分,球隊2和球隊3的比分相差d2分,每場比賽可以任意選擇兩隻隊伍進行。求如果打完最後的 n k 場...
位元組跳動歷屆筆試題(3)
編碼題 字串s由小寫字母構成,長度為n。定義一種操作,每次都可以挑選字串中任意的兩個相鄰字母進行交換。詢問在至多交換m次之後,字串中最多有多少個連續的位置上的字母相同?第一行為乙個字串s與乙個非負整數m。1 s 1000,1 m 1000000 乙個非負整數,表示操作之後,連續最長的相同字母數量。示...
位元組跳動筆試題
要求 輸入陣列長度,然後輸入陣列中的各個元素,最後輸入整數k,要求找出陣列中三個元素小於k的三個元素,例如 輸入陣列長度 6 輸入陣列元素 2 0 1 2 3 6 輸出三元組 共4個 下面給出思路和 思路 1 獲得使用者輸入的陣列長度n,若n不為整數,則提示錯誤。2 建立陣列。3 獲得使用者輸入的陣...