题目描述
下图表示城市之间的交通路网,线段上的数字表示费用,单向通行由A->E。试用动态规划的最优化原理求出A->E的最省费用
输入
输入整数n表示有n个城市
然后是n行n列数据,第i行n个数据表示城市i到各个城市之间的距离,如果没有路径到达该城市,则数据为0
输出
输出最短路径值及经过的城市,格式见样例
样例输入 Copy
10 0 2 5 1 0 0 0 0 0 0 0 0 0 0 12 14 0 0 0 0 0 0 0 0 6 10 4 0 0 0 0 0 0 0 13 12 11 0 0 0 0 0 0 0 0 0 0 3 9 0 0 0 0 0 0 0 0 6 5 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0
样例输出 Copy
minlong=19 1 3 5 8 10
AC代码:
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<iostream>
#define N 1050
using namespace std;
int n,m,k;
int dist[N];
int a[N][N];
int nex[N];
int dp(int u)//前面的点都遍历过后,可以得出前u各点每个点的最优值,最后考虑终点就能成立
{
if(u>=n)//输入值错误直接返回
return 0;
if(dist[u]!=-1)
return dist[u];//已经得出dist的话直接作为dp值返回
for(int i=1;i<=n;i++)
{
if(a[u][i] && (dist[u]==-1 || dist[u]>a[u][i]+dp(i)))//先要走一遍才可以考虑所有情况,所以这里用||
{
dist[u]=a[u][i]+dp(i);
nex[u]=i;//记录下一个走的是哪个点,dist反正是从小到大更新的,不用怕前边没有考虑到
}
}
return dist[u];
}
void dayin(int u)
{
cout<<u<<" ";
if(u==n)
return;
dayin(nex[u]);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
}
memset(dist,-1,sizeof dist);
cout<<"minlong="<<dp(1)<<endl;
dayin(1);
}
下面两段代码引自:Star77777的博客
正推dp:
#include <iostream>
using namespace std;
const int maxn = 1e9;
int mp[10001][10001], dp[10001], p[10001];
void print(int k) {
if (k == 0) return;
print(p[k]);
cout << k << " ";
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
dp[i] = maxn;
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
}
}
dp[1] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j < i; j++) {
if (mp[j][i] && dp[i] > dp[j] + mp[j][i] ) {
dp[i] = dp[j] + mp[j][i];
p[i] = j;
}
}
}
cout << "minlong=" << dp[n] << endl;
print(n);
return 0;
}
逆推dp:
#include <iostream>
using namespace std;
int mp[205][205], p[205], dp[205];
int main()
{
int n, a[205], maxn = 0, k;
cin >> n;
for (int i = 1; i <= n; i++) {
dp[i] = 100000000;
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
}
}
dp[n] = 0;
for (int i = n; i >= 1; i--) {
for (int j = i + 1; j <= n; j++) {
if (mp[i][j] && dp[i] > dp[j] + mp[i][j]) {
dp[i] = dp[j] + mp[i][j];
p[i] = j;
}
}
}
cout << "minlong=" << dp[1] << endl;
k = 1;
while (k) {
cout << k << " ";
k = p[k];
}
cout << endl;
return 0;
}