(1)多源点最短路径问题
问题描述:给定带权有向图G=(V,E),对任意顶点vi和vj,求顶点vi到vj的最短路径长度。
输入(邻接矩阵,-1表示无穷大,即无边):
0 4 11
6 0 2
3 -1 0
输出(所有点对之间的最短路径):
0 4 6
5 0 2
3 7 0
(2)导弹拦截问题
问题描述:某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它能拦截任意高度的导弹,但是每拦截一发导弹,其拦截能力就下降到只能拦截上一次拦截的导弹高度。某天,雷达捕捉到敌国的导弹来袭,导弹依次飞来,该拦截系统最多能拦截多少导弹呢?并输出各拦截的导弹高度。
输入:
8//导弹个数
3890 2070 1550 3000 2990 1700 1580 650//各导弹飞行高度
输出:
6//最多能拦截的导弹个数
3890 3000 2990 1700 1580 650//各拦截的导弹高度
1. #include<iostream> #include<stdlib.h> using namespace std; int main(){ int n=3; int arc[n][n]; int dist[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cin>>arc[i][j]; //初始化代价矩阵arc[n][n] 存储有向边的权值 } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ dist[i][j] = arc[i][j]; //数组dist[n][n]存放在迭代过程中求得的最短路径长度 } } for(int k=0;k<n;k++){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(dist[i][k] + dist[k][j] < dist[i][j] || dist[i][j] == -1){ //满足条件时 可获得最短路径长度 dist[i][j] = dist[i][k] + dist[k][j]; } } } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cout<<dist[i][j]<<" "; //输出最短路径 if(j==2) cout<<endl; } } system("pause"); } 2. #include<iostream> #include<stdlib.h> #include<string.h> using namespace std; void missile_intercept(int daodan[],int lanjie_num[],int n){ for(int i=n-2;i>=0;i--){ //从后往前遍历 for(int j=i+1;j<n;j++){ if(daodan[i]>=daodan[j] && lanjie_num[i]<lanjie_num[j]+1){ //如果前一个导弹的高度大于后一个导弹的高度并且前一个导弹时的拦截数目小于后一个 lanjie_num[i] = lanjie_num[j]+1; //则改变其拦截数目 } } } int nummax =0; //nummax为最多能拦截导弹的个数 int thefirst; //第一个被拦截的导弹 for(int i=0;i<n;i++){ if(lanjie_num[i]>nummax){ nummax = lanjie_num[i]; thefirst = i; } } cout<<nummax<<endl; cout<<daodan[thefirst]<<" "; int then=thefirst; for(int i=thefirst+1;i<n;i++){ if(lanjie_num[i]==lanjie_num[then]-1){ then = i; cout<<daodan[then]<<" "; } } } int main(){ int n; cin>>n; int daodan[n]; for(int i=0;i<n;i++){ cin>>daodan[i]; } int lanjie_num[n]; memset(lanjie_num,0,sizeof(lanjie_num)); //初始化每个导弹处的拦截数目为0 lanjie_num[n-1] = 1; //最后一个导弹处拦截数目为1 missile_intercept(daodan,lanjie_num,n); /* for(int i=n-2;i>=0;i--){ //从后往前遍历 for(int j=i+1;j<n;j++){ if(daodan[i]>=daodan[j] && lanjie_num[i]<lanjie_num[j]+1){ //如果前一个导弹的高度大于后一个导弹的高度并且前一个导弹时的拦截数目小于后一个 lanjie_num[i] = lanjie_num[j]+1; //则改变其拦截数目 } } } int nummax =0; //nummax为最多能拦截导弹的个数 int thefirst; //第一个被拦截的导弹 for(int i=0;i<n;i++){ if(lanjie_num[i]>nummax){ nummax = lanjie_num[i]; thefirst = i; } } cout<<nummax<<endl; cout<<daodan[thefirst]<<" "; int then=thefirst; for(int i=thefirst+1;i<n;i++){ if(lanjie_num[i]==lanjie_num[then]-1){ then = i; cout<<daodan[then]<<" "; } } */ cout<<endl; system("pause"); }
动态规划算法 分析问题的时候从后往前 从右往左 输出解的时候从前往后 从左往右