第九章 動態規劃-1262:【例9.6】挖地雷

【題目描述】
在一個地圖上有n個地窖(n≤200),每個地窖中埋有一定數量的地雷。同時,給出地窖之間的連接路徑,並規定路徑都是單向的,且保證都是小序號地窖指向在序號地窖,也不存在可以從一個地窖出發經過若干地窖後又回到原來地窖的路徑。某人可以從任一處開始挖地雷,然後沿着指出的連接往下挖(僅能選擇一條路徑),當無連接時挖地雷工作結束。設計一個挖地雷的方案,使他能挖到最多的地雷。

【輸入】
第一行:地窖的個數;
第二行爲依次每個地窖地雷的個數;
下面若干行:
xi yi //表示從xi可到yi,xi<yi。
最後一行爲"0 0"表示結束。
【輸出】
k1−k2−…−kvk1−k2−…−kv //挖地雷的順序

挖到最多的雷。
【輸入樣例】
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0

【輸出樣例】
3-4-5-6
34
————————————————
思路:f[i] = max{w[i]+f[j]} 邊界f[i]=w[i]
設w[i]爲第i個地窖所藏地雷數。f[i]表示從第i個地窖開始最多可以挖出地雷數。

#include<cstdio>
#include<iostream>
#define N 210
#define INF 0x3f3f3f3f
using namespace std;
int b[N][N];
int w[N],p[N];
int f[N];// 表示挖到地雷最大數 
void print(int k) //輸出挖地雷的順序 
{
	if(k == 0)
	return;
	print(p[k]);
	if(p[k] == 0)//如果是第一個點 直接輸出k 否則輸出-k 
	cout << k;
	else
	cout << "-" << k; //否則輸出-k 
}
int main(){
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		cin >> w[i];      //輸入 
		f[i] = w[i];
	}
	int x,y;
	while(scanf("%d%d",&x,&y) != EOF && x &&y)
	b[x][y] = 1;//標識x->y通路
	int maxx = -INF, k;
	for(int i = 1; i <= n;i++)
	{
		for(int j = 1; j <= n;j++)
		{
			if(b[j][i] == 1 && f[j]+w[i] > f[i])//j可以到i 且 f[j]+w[i] > f[i]
			{
				f[i] = f[j] + w[i];//保存第i個地窖起挖到的後繼最大地雷數 
				p[i] = j;  //j 地窖是i的最優路徑 
			}
		}
		if(f[i] > maxx)//計算挖到最多地雷數 
		{
			maxx = f[i];
			k = i;
		}
	}
	print(k);
	cout <<endl <<maxx <<endl; 
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章