《三國志》是一款很經典的經營策略類游戲。我們的小白同學是這款游戲的忠實玩家。現在他把游戲簡化一下,地圖上只有他一方勢力,現在他只有一個城池,而他周邊有一些無人占的空城,但是這些空城中有很多不同數量的同種財寶。我們的小白同學虎視眈眈的看著這些城池中的財寶。
按照游戲的規則,他只要指派一名武將攻占這座城池,裡面的財寶就歸他所有了。不過一量攻占這座城池,我們的武將就要留守,不能撤回。因為我們的小白手下有無數的武將,所以他不在乎這些。
從小白的城池派出的武將,每走一公理的距離就要消耗一石的糧食,而他手上的糧食是有限的。現在小白統計出了地圖上城池間的道路,這些道路都是雙向的,他想請你幫忙計算出他能得到 的最多的財寶數量。我們用城池的編號代表城池,規定小白所在的城池為0號城池,其他的城池從1號開始計數。
2 10 1 1 0 1 3 2 5 2 3 0 1 2 0 2 4 1 2 1 2 3
2 5
Dijkstra+貪心算法!
AC碼:
#include#include #define INF 99999999 int G[105][105],visit[105],num[105]; int dist[105],dp[1000005]; int max(int a,int b) { return a>b?a:b; } int main() { int T,s,n,m,a,b,c,min,i,j,k; scanf("%d",&T); while(T--) { scanf("%d%d%d",&s,&n,&m); for(i=0;i<=n;i++) { for(j=0;j<=n;j++) G[i][j]=INF; } for(i=0;i c) // WA了很多次,不知道為什麼要加這個判斷條件 G[a][b]=G[b][a]=c; // 創建鄰接矩陣 } for(i=1;i<=n;i++) scanf("%d",&num[i]); // 每個城市的財富值 // Dijkstra算法求任意兩點間的最短路徑 memset(visit,0,sizeof(visit)); for(i=0;i<=n;i++) dist[i]=G[0][i]; dist[0]=0; visit[0]=1; for(i=1;i<=n;i++) { min=INF; k=0; for(j=0;j<=n;j++) { if(!visit[j]&&min>dist[j]) { min=dist[j]; k=j; } } visit[k]=1; for(j=0;j<=n;j++) { if(!visit[j]&&dist[j]>dist[k]+G[k][j]) dist[j]=dist[k]+G[k][j]; } }// 最短路徑求解完畢 // 貪心算法求得最大財富值 memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=s;j>=dist[i];j--) { dp[j]=max(dp[j],dp[j-dist[i]]+num[i]); } } printf("%d\n",dp[s]); } return 0; }