算法整理(分治法、贪心法、动态规…

分治法:归并排序、快速排序、最大子段和 、最近点对问题

贪心法:多级调度问题、活动安排问题、背包问题

动态规划法:、最大子段和、近似串匹配、最优二叉树  、最长公共子序列、0-1背包问题、多段图最短路径

*******************************************************************

 分治法

 1、归并排序

 // Note:Your choice is C++ IDE

 //归并排序(分治法)

 #include

 using namespace std;

 //合并两个有序子序列

 void Merge( int r1[ ] , int r[ ], int s, int m, int t)

     {

      int i,j,k;

          i=s; j=m+1; k=s;

         while (i<=m && j<=t) {  

             if (r[i]<=r[j]) r1[k++]=r[i++]; 

             else r1[k++]=r[j++];

         }

         if (i<=m) 

  while (i<=m)  

  r1[k++]=r[i++];

         else  

  while (j<=t)     

  r1[k++]=r[j++];

 

  for( i=s; i<=t; i++)

  r[i]=r1[i];    //r[]:第二个数组是合并排序后的序列

     }

    

 //分治法归并排序

 void MergeSort(int r[ ], int r1[ ], int s, int t) {

      int m;

        if (s==t) r1[s]=r[s];   

          else {

             m=(s+t)/2;

             MergeSort(r, r1, s, m);    //归并排序前半个子序列

             MergeSort(r, r1, m+1, t);   //归并排序后半个子序列

             Merge(r, r1, s, m, t);      //合并两个已排序的子序列

          }

     }

    

 int main()

 {

     int r[256],r1[256];

     int t;

     cin>>t;

     for(int i=1; i<=t; i++)

      cin>>r[i];

    

     int s=1;

    

     MergeSort( r,  r1,  s,  t) ;

 

     for( i=1; i<=t; i++)

      cout<

     return 0;

 }

 ===================================

 2、快速排序

 #include

 

 void Swap(int a[], int m, int n){

     int temp;

     temp= a[m];

  a[m]= a[n];

  a[n] =temp;

 }

 

 int Partition(int r[ ], int first, int end)

      {

         int   i=first  ,j=end;         //初始化

           while (i

           {  

        while (i

                if (i

                   Swap(r,i,j);            //将较小记录交换到前面

                   i++; 

                }

        while (i

               if (i

                 Swap(r,i,j);              //将较大记录交换到后面

                  j--; 

               }

           }

           return i;    // i为轴值记录的最终位置

     }

 void QuickSort(int r[ ], int first, int end)

   {

      if (first

         int pivot=Partition(r, first, end);  

         QuickSort(r, first, pivot-1); 

         QuickSort(r, pivot+1, end);

      }

   }

 

 void main(){

   int n,r[100],i;

   cin>>n;

   for( i=1; i<=n; i++)

   cin>>r[i];

     QuickSort(r,0,n);

    for( i=1; i<=n; i++)

  cout<

 }

 

 ===========================================

 3、最大子段和 

 一、蛮力法

 #include

 int BFMaxSum(int a[ ], int n){

        int sum=0, i,j;  

    for(i=0; i

    int s1=0;   //s1的复原为零很重要;

    for(j=i; j

  s1 += a[j];

  if (s1 > sum)   sum = s1;

      //cout<

    }

    }

  return sum;

 }

 void main(){ 

   int a[100];

   int i,n;

  cout<<"请输入整数个数:";

   cin>>n;

   cout<<"请输入这"<

   for(i=0; i

   cin >> a[i];

   int rs=BFMaxSum( a, n);

   cout<<"该序列的最大字段和为:"<

 }

 

 二、分治法

 #include

 int MaxSubSum(int a[ ], int left, int right) {

        int sum=0,i,j;

        //如果序列长度为1,直接求解

        if (left==right) {      

            if (a[left]>0)    sum=a[left];

            else   sum=0;

        }

       else {

          int  center=(left+right)/2;    //划分

           int leftsum=MaxSubSum(a, left, center); 

           int rightsum=MaxSubSum(a, center+1, right);   

  

            //以下对应情况③,先求解s1      

          int   s1=0, lefts=0;            

         for (i=center; i>=left; i--){

             lefts+=a[i];

             if (lefts>s1) s1=lefts;

         }

        int  s2=0, rights=0;             //再求解s2

        for (j=center+1; j<=right; j++){ 

             rights+=a[j];

             if (rights>s2) s2=rights;

         }

         sum=s1+s2;              //计算情况③的最大子段和 

         //合并,在sum、leftsum和rightsum中取较大者

         if (sum

         if (sum

      }

      return sum;

 }

 void main(){

   int a[100];

   int i,n;

   cout<<"请输入整数个数:";

   cin>>n;

   cout<<"请输入这"<

   for(i=0; i

   cin >> a[i];

   int rs=MaxSubSum( a,  0, n-1);

   cout<<"该序列的最大字段和为:"<

 }

 

 三、动态规划法

 参考动态规划法中的。。

 ==============================================================

 4、最近点对问题

 一、参考

 #define inf 9999999

 #include

 #include

 #include

 using namespace std;

 struct point

 {

     double x , y;

 }p[100005];

 int a[100005];    //保存筛选的坐标点的索引

 

 bool cmpx( point a , point b){    //结构体数组的排序//这里用的是下标索引

     return a.x < b.x;

 }

 bool cmpy(int a , int b){

     return p[a].y < p[b].y;

 }

 

 double dis(point a , point b){

     return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));

 }

 double min(double a , double b){

     return a < b ? a : b;

 }

 

 double closest(int low , int high)

 {

     if(low==high)

     return inf;   //1、如果n=1,返回无限大值

     int mid = (low + high)>>1;   //除2操作可为右移一位;  2、得到中点数

     double ans = min( closest(low , mid) , closest(mid + 1 , high) );  //分治法

 

     int i , j , cnt = 0;

     for(i = low ; i <= high ; ++i)

     {

         if(p[i].x >= p[mid].x - ans && p[i].x <= p[mid].x + ans)

             a[cnt++] = i;   //a[]数组记录点的坐标

     }

  sort(a , a + cnt , cmpy);

     for(i = 0 ; i < cnt ; ++i)

     {

         for(j = i+1 ; j < cnt&&j<=i+7 ; ++j)

         {

             if(p[a[j]].y - p[a[i]].y >= ans)

                 break;

             ans = min(ans , dis(p[a[i]] , p[a[j]]));

         }

     }

     return ans;

 }

 int main()

 {

     int i,n;

     while(scanf("%d",&n) != EOF)

     {

         if(!n)

             break;

         for(i = 0 ; i < n ; ++i)

             scanf("%lf %lf",&p[i].x,&p[i].y);

         sort(p , p + n , cmpx);

         printf("%.2lf\n",closest(0 , n - 1));

     }

     return 0;

 }

 

 二、蛮力法

 #include

 using namespace std;

 int main()

 {

     int n,i,j,x[256],y[256],index1=0,index2=0;

     int d,min;

     cin>>n;

     for(i=0; i

      cin>>x[i]>>y[i];

 

     //先假定第一个和第二个点间的距离为所有点对的距离的最小值

     min=(x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2]);

 

     //为了避免同一对点计算两次,只考虑i

     for(i=0; i

      for(j=i+1; j

      //d为点对间的距离,运用打擂台的思想

      d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);

      //index1,index2记录点对

      //min即为最后所有点对间的最小距离值

      if(d<=min){

      min=d;

      index1=i+1;

      index2=j+1;

      }

      }

      cout<<"距离最短的两个点是第"<

      cout<<"最近的距离的平方是"<

     return 0;

 }

 三、分治法

   与最大子段和的分治法很相像

 #include

 //#include

 #include

 #define Max 10000000

 using namespace std;

 int min(int a,int b){    //求两数最小值

  return  ( a>=b ) ? b : a;

 }

 int abs(int a){     //绝对值

  return a>0? a: -a;

 }

 int dis(int x1, int y1, int x2, int y2){ //距离

  cout<<"计算的距离:"<

  return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);

 }

 

 int ClosePoints(int n,int s[][2]){  //用二维数组存放点的横纵坐标

  //1、点的个数应该大于2

  if (n < 2) return Max;

  if(n==2) return dis(s[0][0],s[0][1],s[1][0],s[1][1]);

 

     int m=0,i,j;

     int s1[256][2],s2[256][2];

       

     //2、m为s中x坐标的中位数

     sort(s,s+n);

  m=(s[0]+s[n-1])/2;

    // for(i=0; i

      //  m += s[i][0];

   // cout<<"s: "<

     //}

     //m /= n;

     

  //3、构造s1和s2, 使得s1中的x坐标小于m,s2中点的坐标大于m

  int k=0;

  int h=0;

  for(i=0;i

  {

  if(s[i][0]

  {

  s1[h][0]=s[i][0];

  s1[h++][1]=s[i][1];

  }

  else

  {

  s2[k][0]=s[i][0];

  s2[k++][1]=s[i][1];

  }

  }

      

  //4、分治法

  cout<

  int d1=ClosePoints(h,s1);

  int d2=ClosePoints(k,s2);

  

  //5、使得d为S1中的最近距离d1和S2中的最近距离d2的最小值

  int d=min(d1,d2);

 

  //6、构造p1和p2,使得p1是s1中点的x坐标与m的距离小于d的点集,p2是s2中点的x坐标与m的距离小于d的点集 

  int c=0,f=0;

  int p1[256][2],p2[256][2];

 

  for(i=0; i

  {

  if(abs(s1[i][0]-m)

  for(j=0; j<2; j++)

  p1[c++][j]=s1[i][j];  

  }

  //输出s1数组

  cout<<"s1: "<

  }

  for(i=0; i

  {

  if(abs(s2[i][0]-m)

  for(j=0; j<2; j++)

  p2[f++][j]=s2[i][j];

  }

  //输出s2数组

  cout<<"s2: "<

  }

 

  //7、将p1和p2中点的按y坐标升序排列    

  int temp;

  for(i=0; i

  for(j=1; j

  if(p1[j-1][1]>p1[j][1]){

  temp=p1[j][1];

  p1[j][1] = p1[j-1][1];

  p1[j+1][1] = temp;

 

  temp=p1[j][0];

  p1[j][0] = p1[j-1][0];

  p1[j+1][0] = temp;

  }        

  }

  //输出排序后的p1数组

  for(i=0; i

  cout<<"p1: "<

  

  for(i=0; i

  for(j=1; j

  if(p2[j-1][1]>p2[j][1]){

  temp=p2[j][1];

  p2[j][1] = p2[j-1][1];

  p2[j+1][1] = temp;

 

  temp=p2[j][0];

  p2[j][0] = p2[j-1][0];

  p2[j+1][0] = temp;

  }        

  }

     //输出排序后的p2数组

  for(i=0; i

  cout<<"p2: "<

     cout<

 

  //8、对p1中的每一个点p,在p2中查找与点p的y坐标小于d的点,并求出其中的最小距离dmin

  int dmin=0;

  if(c!=0 && f!=0)

  dmin=dis(p1[0][0],p1[0][1],p2[0][0],p2[0][1]);

  else return min(d,Max);

 

  for(i=0; i

  for(j=0; j

  if( abs(p1[i][1]-p2[j][1])

  dmin = dis(p1[i][0], p1[i][1], p2[j][0], p2[j][1]);

  d=dmin;

  }

  }

  }

  //9、返回最小值d

      return min(d,dmin);      

 }

  

 int main()

 {

  int s[256][2];

  int n,i,j;

  cin>>n;

     //依次输入n个点的x,y坐标

     for(i=0; i

  for(j=0; j<2; j++)

  cin>>s[i][j];

    

     int rd= ClosePoints(n,s);

    

     cout<<"最近点对间的距离为:";

  cout<

 

     return 0;

 }

 ==============================

 ******************************************

 贪心法

 1、多级调度问题

 #include

 #include

 #include

 #include

 using namespace std;

 struct Data

  {

      int data;

     int index;

  };

 Data t[100];

 Data d[100];

 bool cmp(Data a,Data b){  //实现结构体数组按照data项进行从大到小排序

  return a.data > b.data ;

 }   

 int  sortmin(Data d[], int n){  //寻找d[]数组中的最小值

  int i,indexs=0;

  for(i=0; i

  if(d[i].data < d[indexs].data )

  indexs=i;

  }

  return indexs;

 }

 void duoji(Data t[],  int n, int m){

  int i,  S[100][100],  p[100] ,  h[100];

  Data d[100];

  memset(h,0,sizeof(h));

 

  sort(t,t+n,cmp);   //结构体的排序

  cout<

  for(i=0; i

  p[i]=t[i].index;  //1、将t[]排序后,按照从大到小将作业号存储在p[]数组中

     cout<

  }

  cout<

 for(i=0; i

  d[i].data=0;

  d[i].index=i;

  }

 

  if(n

  for(i=0; i

  S[i][0]=p[i] ;   

  d[i].data = t[i].data ;

  cout<<"第"<

  <<"所需时间分别为: "<

  }

 }

  else{  //B、当作业数n > 机器数m的情况

  for(i=0; i

  S[i][0]=p[i] ;   

  d[i].data = t[i].data ;

  cout<<"第"<

  <<"所需时间为: "<

  }

  for(i=m; i

  int j=sortmin(d,m);

  cout<<"下一次为机器 "<

  S[j][++h[j]]=p[i];

  cout<<"  ,并且此次机器"<

  d[j].data += t[i].data;

  cout<

  }

 }

 }

 int main()

 {

     int i,n,m;

     cout<<"输入作业个数n和机器个数m: ";

     cin>>n>>m;

     cout<<"输入完成各作业所需要的处理时间:"<

     for(i=0; i

     cin>>t[i].data;

     t[i].index=i;

     }

     cout<

     cout<

     duoji( t, n,  m);       

     return 0;

 }

 ====================================================

 2、活动安排问题

 4

 1 4

 3 5

 0 6

 5 7

 #include

 #include

 using namespace std;

 struct Data{

    int s,f;

 }time[100];

 

 bool cmp(Data a, Data b){

   return a.f<= b.f;

 }

 

 void ActiveManage(Data time[], bool a[ ], int n)

     {  //各活动的起始时间和结束时间存储于数组s和f中且

         //按结束时间的非减序排列 

  sort(time+1, time+n+1, cmp);

  int i,j,count, rode[100],k=1;  

     a[1]=1;

     j=1; count=1; rode[1]=1;

     for (i=2; i<=n; i++) //从 活动i 开始寻找与 活动j 相容的活动,j从1开始 ,如此循环贪心寻找

         { 

            if ( time[i].s >= time[j].f ) {

               a[i]=1;

               j=i;

   rode[++k]=i;

               count++;

            }

            else a[i]=0;

         }

  cout <<"共有"<

         for(i=1; i<=k; i++)

         cout<<"活动:"<

 }

 

 void main(){

  int n,i;

  bool a[100];

  cin>>n;

  for(i=1; i<=n; i++)

     cin>>time[i].s>>time[i].f;

 

    ActiveManage(time,a,n);

 }

 ===================================

 3、背包问题

 3

 20 30 10

 60 120 50

 50

 #include

 #include

 using namespace std;

 struct Data

  {

      float data;

      int index;

  };

  Data origData[100];

 

  bool cmp(Data a, Data b){

   return a.data>b.data;

  }

 float Bag(float w[],float v[],float C,int n){

  int i,x[100];

  float vsum=0;

  float r[100], w1[100], v1[100];

  for(i=1; i<=n; i++)

  r[i]=v[i]/w[i];

     

  for ( i=1; i<=n; i++){    //初始化OrigData[]数组,记录v[i]/w[i]

      origData[i].data = r[i];

      origData[i].index = i;

  }

  sort(origData+1,origData+n+1,cmp);  //排列OrigData[]数组   又是下标的问题

 

  for(i=1; i<=n; i++){      //根据v[i]/w[i]的降序排列重排列w[]和v[]

  w1[i]=w[origData[i].index];

  v1[i]=v[origData[i].index];

  }

  

   memset(x,0 , sizeof(x));

    i=1; 

  while(w1[i]<=C){

  origData[i].data=1;

  C -= w1[i];

  vsum +=v1[i];

  i++;

  }

     origData[i].data = C/w1[i];

  vsum += v1[i] * origData[i].data;   //此处纠结了好久。。。

  cout<<"所选物品及百分比为:(1代表全选,0代表不选)"<

  for(int j=1; j<=i; j++)

  cout<

  cout<

  return vsum; 

 }

 void  main(){

    int n,i,j;

    float vsum=0;

     float w[100],v[100],C;

     cout<<"输入物品的数量:";

     cin>>n;

     cout<<"输入这"<

     for(i=1; i<=n; i++)

     cin>>w[i]; 

      cout<<"输入这"<

     for(j=1; j<=n; j++)

     cin>>v[j];

     cout<<"输入背包容量C:"<

     cin>>C; 

 

     float rs=Bag(w,v,C,n);

     cout<<"背包中的物品最大价值容量为:"<

 }

 =============================================

 **********************************************

 动态规划法

 1、最大子段和

 #include

 #include

 using namespace std;

 //数列b[]代表前j个数的最大子段和(是加上a[j]的值)

 int DPMaxSum(int a[ ], int n){

        int j,b[100];

        b[1]=a[1];  //下标为1到n  

 

    for(j=2; j<=n; j++){

  if(b[j-1]>0)   b[j]=b[j-1]+a[j];

  else    b[j] = a[j];

    }

 

    sort(b+1,b+n+1); //注意数组与此处排序函数的一致性

                          -------------------------(还有一个递推式)

    return b[n];

 }

 void main(){

   int a[100];

   int i,n;

   cout<<"请输入整数个数:";

   cin>>n;

   cout<<"请输入这"<

   for(i=1; i<=n; i++)

   cin >> a[i];

   int rs=DPMaxSum(a, n);  

   cout<<"该序列的最大字段和为:"<

 }

 =================================================

 2、近似串匹配

 5 14 1

 happy

 Have a hsppy day!

 //-----唯一的问题是不识别空格符

 #include

 int min(int a,int b,int c){

  int min=a;

  if(a>=b) min =b;

  if(min >=c)  min=c;

  return min;

 }

 //P[m]数组存放输入的样本,T[n]数组存放匹配的文本, K-近似匹配

 //D[i][j]数组存放样本P前缀p1到pi与文本T前缀T1到Tj的最小差别数

 int ASM(char P[ ], char T[ ], int m, int n, int K){

  int j,i, D[100][100];

          for (j=1; j<=n; j++)   //初始化第0行

          D[0][j]=0;

          for (i=0; i<=m; i++)   //初始化第0列

             D[i][0]=i;

          for (j=1; j<=n; j++)    //根据递推式依次计算每一列

         {

             for (i=1; i<=m; i++)

             {

                 if ( P[i]==T[j] ) 

                     D[i][j]= min( D[i-1][j-1], D[i-1][j]+1, D[i][j-1]+1);

                 else

                     D[i][j]=min( D[i-1][j-1]+1, D[i-1][j]+1, D[i][j-1]+1);

             }

             if ( D[m][j]<=K) return j; //输出匹配末位置

          }

     }

 void main(){

  char P[100], T[100];

   int i,m,n,K;

   cout<<"请输入样本字符数m,文本字符数n 和 K值:"<

   cin>>m>>n>>K;

   cout<<"请输入样本字符串和文本字符串:"<

   for(i=1; i<=m; i++)

   cin>>P[i];

   for(i=1; i<=n; i++)

   cin>>T[i];   

   cout<<"最大匹配数是:"<

 }

 ====================================================

 3、最优二叉树        

 请输入字符个数n:

 4

 请输入字符的查找概率

 0.1 0.2 0.4 0.3

 最优二叉查找树的平均比较次数是:1.7

 Press any key to continue

 

 #include

 #define MAX 999

 //数组p[]存放n个字符的查找概率

 //数组C[i][j]是二叉查找树T(i,j)的平均比较次数

 //数组R[i][j]是二叉查找树T(i,j)的根节点序号

 double OptimalBST( int n, double p[100 ], double C[100 ][100 ], int R[ 100][100 ] ){

  int i,j,d;

  for (i=1; i<=n; i++)  {  //初始化

           C[i][i-1]=0;

           C[i][i]=p[i];

           R[i][i]=i;

        }

        C[n+1][n]=0;

    for (d=1; d

     for (i=1; i<=n-d; i++){

          j=i+d;

  double min, sum;

  int mink;  

         min=MAX; mink=i; sum=0;

         for (int k=i; k<=j; k++){

            sum=sum+p[k];

            if (C[i][k-1]+C[k+1][j]

               min=C[i][k-1]+C[k+1][j];

               mink=k;

            }

         }

         C[i][j]=min+sum;

         R[i][j]=mink;

      }

      return C[1][n];

 }

 

 void main(){

   int i, R[100][100] ,n ;

   double P[100],C[100][100];

   cout<<"请输入字符个数n:"<

   cin>>n;

   cout<<"请输入字符的查找概率"<

   for(i=1; i<=n; i++)

    cin>>P[i];

   cout<<"最优二叉查找树的平均比较次数是:"<

 }

 =========================================

 4、最长公共子序列

 

 输入两个序列的个数m,n:

 6 9

 a b c b d b

 a c b b a b d b b

 最长公共子序列是:a c b d b

 最长公共子序列的长度是:5

 Press any key to continue

 

 #include

 //L[i][j]为序列x[i]与y[j]序列的最长公共子序列的长度

 //S[][]记录三种状态,回溯最长公共子序列

 int CommonOrder(int m, int n, char x[ ], char y[ ], char z[]){

  int L[100][100],i,j,k,S[100][100];

       for (j=0; j<=n; j++)   //初始化第0行

          L[0][j]=0;

       for (i=0; j<=m; i++)   //初始化第0列

          L[i][0]=0;

 

       for (i=1; i<=m; i++)

          for (j=1; j<=n; j++)

             if (x[i]==y[j]) { 

  L[i][j]= L[i-1][j-1] +1; 

  S[i][j] = 1; 

  }

            else if (L[i][j-1] >= L[i-1][j]) { 

    L[i][j] = L[i][j-1]; 

    S[i][j]=2; 

    }

           else {

  L[i][j]=L[i-1][j]; 

  S[i][j]=3; 

   }

   cout<<"最长公共子序列是:";

        i=m; j=n; k=L[m][n];

       while (i>0 && j>0) {

          if (S[i][j]==1) { 

  z[k]=x[i]; 

  k--; i--; j--; 

  }

         else if (S[i][j]==2)  j--;

           else i--;

      }

   for(i=1; i<=L[m][n]; i++)

   cout<

  cout<

      return L[m][n];

   }

 void main(){

     char x[100],y[100],z[100];

  int n,m;

  cout<<"输入两个序列的个数m,n:"<

  cin>>m>>n;

  for(int i=1; i<=m; i++)

  cin>>x[i];

  for(i=1; i<=n; i++)

  cin>>y[i];

   cout<<"最长公共子序列的长度是:"<

 }

 ======================================

 5、0-1背包问题

 输入物品数量:

 3

 输入这3个物品的重量:

 20 30 10

 输入这3个物品的价值:

 60 120 50

 输入背包容量C:

 50

 输出装入背包的物品:1表示装入,0表示未装入

 1 1 0

 背包中的物品最大价值容量为:180

 Press any key to continue

 

 #include

 int max(int a,int b){

 return a>b ? a : b;

 }

 //V[i][j]表示在前i个物品中能够装入容量为j的背包中的物品的价值最大值

 //V[i][0] , V[0][j]都为0;

 int KnapSack(int n, int w[ ], int v[ ],int C) {      //n个物品,C为最大容量

     int i,j;

     int V[100][100],x[100];

 

      for (i=0; i<=n; i++)   //初始化第0列

        V[i][0]=0;

      for (j=0; j<=C; j++)   //初始化第0行

        V[0][j]=0;

 

      for (i=1; i<=n; i++)   //计算第i行,进行第i次迭代

        for (j=1; j<=C; j++)

           if (j

           V[i][j]=V[i-1][j];

          else      //满足装入条件(装入后未超重),但也可不装

  V[i][j]=max(V[i-1][j], V[i-1][j-w[i]]+v[i]);  //装或者不装后的价值的最大值

 

  //求装入背包的物品:1表示装入,0表示未装入

     j=C;   

     for (i=n; i>0; i--){

         if (V[i][j]>V[i-1][j]) {

           x[i]=1;

           j=j-w[i];

  }

        else x[i]=0;

 }

  //输出装入背包的物品:1表示装入,0表示未装入

     cout<<"输出装入背包的物品:1表示装入,0表示未装入"<

  for(i=1; i<=n; i++)

  cout<

  cout<

  

  return V[n][C];    //返回背包取得的最大价值

 }

 int main(){

     int n,i,j,w[100],v[100],C;

     cout<<"输入物品数量:"<

     cin>>n;

  cout<<"输入这"<

     for(i=1; i<=n; i++)

     cin>>w[i];

  cout<<"输入这"<

     for(j=1; j<=n; j++)

     cin>>v[j];

  cout<<"输入背包容量C:"<

     cin>>C;

 

     cout<<"背包中的物品最大价值容量为:"<

     return 0;

 }

 ========================================

 6、多段图最短路径

 输入城市个数:10

 输入城市之间的距离:

 100 4 2 3 100 100 100 100 100 100

 100 100 100 100 9 8 100 100 100 100

 100 100 100 100 6 7 8 100 100 100

 100 100 100 100 100 4 7 100 100 100

 100 100 100 100 100 100 100 5 6 100

 100 100 100 100 100 100 100 8 6 100

 100 100 100 100 100 100 100 6 5 100

 100 100 100 100 100 100 100 100 100 7

 100 100 100 100 100 100 100 100 100 3

 100 100 100 100 100 100 100 100 100 100

 最短路径长为:16

 最短路径为:0->3->5->8->9

 Press any key to continue

 

 #include

 //cost[i]表示从顶点i到顶点n-1 的最短路径

 //path[i]表示从顶点i到顶点n-1的最短路径上的下一顶点

 void duoduantu(int cost[100],int c[100][100],int path[100],int k,int n){

  int i,j;

  for(i=0; i

    cost[i]=c[i][n-1];  //初始,c[][]记录各顶点间的距离  

  for(i=n-2; i>=k; i--)

  for(j=i+1; j

  if( (cost[j] + c[i][j]) < cost[i]){

  cost[i]= cost[j] + c[i][j] ;

  path[i]=j;

  }

 }

 int main(){

    int i,j,n;

    int c[100][100], cost[100], path[100];

    cout<<"输入城市个数:";

    cin>>n;

    cout<<"输入城市之间的距离:";

    for(i=0; i

    for(j=0; j

    cin>>c[i][j];

    

  duoduantu(cost,c,path,0,n);

  cout<<"最短路径长为:"<

 

  for(i=0; i<=n-2; i++)

  duoduantu(cost,c,path,i,n);

  cout<<"最短路径为:"<<0<<"->";

         i=0;

  do{

  cout<

  if(i!=n-2) cout<<"->";

  i=path[i];

  }while(i

  cout<

    return 0;

 }

 =========================================

你可能感兴趣的:(计算机)