算法作业

第二章

1、整数划分

#include<iostream>
#include <cmath>
#include <cstdio>
using namespace std;

int m[10];
int n;

void Divid(int now,int k,int pr) { int i; if(now > n) return; if(now == n) { for(i = 0; i < k-1; i++) printf("%d+",m[i]); printf("%d\n",m[i]); } else { for(i = pr; i > 0; i--) { m[k]=i; now+=i; Divid(now,k+1,i); now-=i; } } } int main() { scanf("%d",&n); Divid(0,0,n); return 0; }

 2、大整数乘法

 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 int stringToInt(string s)
 7 {
 8     int sum=0;
 9     int flag=1;
10     for(int i=0;i<s.size();i++) 11  { 12 if(s[i]=='-') 13  { 14 flag=-1; 15 continue; 16  } 17 sum = sum*10 + s[i]-'0'; 18  } 19 return flag*sum; 20 } 21 22 int mul(int a,int b,int n) 23 { 24 int flag; 25 if((a<0 && b<0) || (a>0 && b>0) ) 26 flag=1; 27 else 28 flag=-1; 29 30 a=abs(a); 31 b=abs(b); 32 33 if(a==0 && b==0) 34  { 35 return 0; 36  } 37 if(n==1) 38  { 39 return flag*a*b; 40  } 41 42 int a1=a/pow(10,n/2); 43 int a2=a-a1*pow(10,n/2); 44 int b1=b/pow(10,n/2); 45 int b2=b-b1*pow(10,n/2); 46 int ac=mul(a1, b1, n/2); 47 int bd=mul(a2, b2, n/2); 48 int ab=mul(a1-a2,b2-b1,n/2)+ac+bd; 49 return flag*(ac*pow(10, n)+ab*pow(10, n/2)+bd); 50 51 } 52 53 int main() 54 { 55 string s1,s2; 56 int a,b; 57 cin>>s1>>s2; 58 int len; 59 60 int len1=s1.size(); 61 int len2=s2.size(); 62 if(s1[0]=='-') 63 len1--; 64 if(s2[0]=='-') 65 len2--; 66 67 if(len1!=len2) 68  { 69 cout<<"输入错误!"<<endl; 70 return 0; 71  } 72 len=len1; 73 a=stringToInt(s1); 74 b=stringToInt(s2); 75 cout<<"参照:"<<a*b<<endl; 76 cout<<mul(a,b,len)<<endl; 77 return 0; 78 }

 3、合并排序

 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int MAX=1000;
 7 int a[MAX];
 8 int b[MAX];
 9 
10 void mymerge(int a[],int b[],int left,int mid,int right)
11 { 12 int i=left,j=mid+1,k=0; 13 while(i<=mid && j<=right) 14  { 15 if(a[i]<a[j]) 16  { 17 b[k++]=a[i++]; 18  } 19 else 20  { 21 b[k++]=a[j++]; 22  } 23  } 24 25 if(i>mid) 26  { 27 for(int q=j;q<=right;q++) 28 b[k++]=a[q]; 29  } 30 else 31  { 32 for(int q=i;q<=mid;q++) 33 b[k++]=a[q]; 34  } 35 36 } 37 38 void mycopy(int a[],int b[],int left,int right) 39 { 40 for(int i=left,j=0;i<=right ;i++,j++) 41 a[i]=b[j]; 42 43 } 44 45 void mergeSort(int a[],int left,int right) 46 { 47 if(left<right) 48  { 49 int mid=(left+right)/2; 50  mergeSort(a, left, mid); 51 mergeSort(a, mid+1, right); 52  mymerge(a,b,left,mid,right); 53  mycopy(a,b,left,right); 54  } 55 } 56 57 void show(int a[],int n) 58 { 59 for(int i=0;i<n;i++) 60  { 61 cout<<a[i]<<" "; 62  } 63 cout<<endl; 64 } 65 66 int main() 67 { 68 int n; 69  srand(time(NULL)); 70 cin>>n; 71 for(int i=0;i<n;i++) 72 a[i]=rand()%(n*10); 73  show(a, n); 74 mergeSort(a,0,n-1); 75  show(a, n); 76 return 0; 77 }

 4、循环赛日程表

 1 #include <iostream>
 2 using namespace std;
 3 void odd_table ( int **a , int n)
 4 {
 5     int i,j;
 6     int *b;        //指向对阵关系数组
 7 
 8     //建立初始对阵关系(,n-1,2,n-2,...,i,n-i)
 9     b=new int [n];        //0下标不用
10     for(i=1;i<=n/2;i++)
11  { 12 b[2*i-1]=i; 13 b[2*i]=n-i; 14  } 15 16 for(i=1;i<=n;i++)//i控制天数变化 17  { 18 a[i][i]=0; //n为奇数时在第i天第i号运动员轮空 19 for(j=1;j<=(n-1);j+=2) 20  { 21 //第i天m1与m2对阵 22 int m1=((b[j]+i)<=n)?(b[j]+i):(b[j]+i)%n; 23 int m2=((b[j+1]+i)<=n)?(b[j+1]+i):(b[j+1]+i)%n; 24 a[m1][i]=m2; 25 a[m2][i]=m1; 26  } 27  } 28 } 29 30 int main() 31 { 32 int i,j; //循环控制变量 33 int days; //比赛天数 34 int n; //参赛队数 35 int **a; //日程表 36 37 cout<<"请输入运动员人数:"; 38 cin >> n; 39 40 if (n<=1) cout<<"数据非法"; 41 else 42  { 43 a=new int* [n+1]; //行表示运动员 44 days = n%2==0?n-1:n; //比赛天数,n是偶数时,n-1天。n是奇数时,n天. 45 for(int i=1;i<=(n+1);i++) 46 a[i] = new int [days+1]; 47  } 48 49 if(n%2!=0) 50  odd_table(a,n); 51 else 52  { 53 odd_table(a,n-1); 54 //加入第n个运动员的比赛日程,只需将其加入到前n-1个运动员日程中轮空位置即可 55 for(i=1;i<=n;i++) //i控制天数变化 56  { 57 a[i][i]=n; 58 a[n][i]=i; 59  } 60  } 61 62 //输出表头 63 cout<<"\n\t"; 64 for(j=1;j<=days;j++) 65 cout<<"第"<<j<<"天 "; 66 cout<<endl; 67 //输出比赛日程 68 for(i=1;i<=n;i++) 69  { 70 cout<<"第"<<i<<"号"<<" "; 71 for(j=1;j<=days;j++) 72 cout<<a[i][j]<<" "; 73 cout<<'\n'; 74  } 75 }

 5、快速幂

代码:

#include <iostream>
#include <cmath>
#include <cstdio>
#include <queue>
#include <string>
#include <cstring>
using namespace std; double po(double a,int b) { int flag=0; if (b<0) { flag=1; b=-b; } double ans=1; while (b!=0) { if((b&1)==1) ans*=a; a*=a; b>>=1; } if (flag) return 1/ans; return ans; } int main() { int a,b; cin>>a>>b; cout<<po(a,b)<<endl; }

输入示例:

3 4

输出示例:

81

 6、二分递归版

代码:

 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstdio>
 4 #include <queue>
 5 #include <string>
 6 #include <cstring>
 7 using namespace std;
 8 
 9 int bsearch(int* num,int l,int r,int n)
10 {
11     int mid=(l+r)/2;
12     if(l>r)
13         return -1; 14 if (num[mid]==n) 15 return mid; 16 else if(num[mid]>n) 17 return bsearch(num, l, mid-1, n); 18 else 19 return bsearch(num, mid+1, r, n); 20 } 21 22 23 int main() 24 { 25 int num[11]; 26 for(int i=1;i<11;i++) 27 num[i]=i; 28 int n; 29 cin>>n; 30 cout<<bsearch(num,1,10,n)<<endl;; 31 32 return 0; 33 }

输入示例:

5

输出示例:

5

 第三章 DP

DP之矩阵连乘

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn=100;
 8 
 9 void MinNum(int n,int p[],int m[maxn][maxn],int s[maxn][maxn])
10 {
11     for(int i=1;i<=n;i++)
12         for(int j=1;j<=n;j++) 13 m[i][j]=0x3f3f3f3f; 14 for(int i=1;i<=n;i++) m[i][i]=0; 15 for(int len=1;len<n;len++) 16  { 17 for(int i=1;i<=n-len;i++) 18  { 19 int j=i+len; 20 for(int k=i;k<j;k++) 21  { 22 int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; 23 if(t<m[i][j]) 24  { 25 m[i][j]=t; 26 s[i][j]=k; 27  } 28  } 29  } 30  } 31 } 32 33 void show(int i,int j,int s[maxn][maxn]) 34 { 35 if(i==j) return; 36  show(i,s[i][j],s); 37 show(s[i][j]+1,j,s); 38 cout<<"A"<<i<<"x"<<"A"<<s[i][j]<<" "; 39 cout<<"A"<<s[i][j]+1<<"x"<<"A"<<j<<endl; 40 } 41 42 int main() 43 { 44 int n; 45 int p[maxn]; 46 cin>>n; 47 for(int i=0;i<=n;i++) 48 cin>>p[i]; 49 int m[maxn][maxn],s[maxn][maxn]; 50 51  MinNum(n,p,m,s); 52 cout<<"最少乘法次数为:"<<m[1][n]<<endl; 53 show(1,n,s); 54 } 55 /* 56 6 57 30 35 15 5 10 20 25 58 */

 

 DP之最长公共子序列
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn=1000;
 8 
 9 void f(int nm,int nn,char p[],char q[],int m[maxn][maxn],int s[maxn][maxn])
10 {
11     for(int i=0;i<=nm;i++) m[0][i]=0;
12     for(int i=0;i<=nn;i++) m[i][0]=0; 13 for(int i=1;i<=nm;i++) 14  { 15 for(int j=1;j<=nn;j++) 16  { 17 if(p[i-1]==q[j-1]) 18  { 19 //cout<<m[i-1][j-1]<<"jj"<<endl; 20 m[i][j]=m[i-1][j-1]+1; 21 s[i][j]=1; 22  } 23 else if(m[i-1][j]>=m[i][j-1]) 24  { 25 m[i][j]=m[i-1][j]; 26 s[i][j]=2; 27  } 28 else 29  { 30 m[i][j]=m[i][j-1]; 31 s[i][j]=3; 32  } 33 34  } 35  } 36 cout<<"最长公共子序列长度为:"<<m[nm][nn]<<endl; 37 38 } 39 40 void show(int i,int j,char *c,int s[maxn][maxn]) 41 { 42 if(i==0 || j==0) 43 return ; 44 if(s[i][j]==1) 45  { 46 show(i-1,j-1,c,s); 47 cout<<c[i-1]; 48 49  } 50 else if(s[i][j]==2) 51  { 52 show(i-1, j, c, s); 53  } 54 else 55 show(i,j-1,c,s); 56 } 57 58 int main() 59 { 60 string s1,s2; 61 cin>>s1>>s2; 62 char c1[maxn],c2[maxn]; 63 int num1=s1.length(); 64 int num2=s2.length(); 65  strcpy(c1,s1.c_str()); 66  strcpy(c2,s2.c_str()); 67 int m[maxn][maxn],s[maxn][maxn]; 68  f(num1,num2,c1,c2,m,s); 69 cout<<"最长公共子序列为:"; 70  show(num1,num2,c1,s); 71 cout<<endl; 72 73 }

DP之01背包问题

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N=100;
 7 int main()
 8 {
 9     int v[N]={0,8,10,6,3,7,2};
10     int w[N]={0,4,6,2,2,5,1}; 11 12 int m[N][N]; 13 int n=6,c=12; 14 memset(m,0,sizeof(m)); 15 for(int i=1;i<=n;i++) 16  { 17 for(int j=1;j<=c;j++) 18  { 19 if(j>=w[i]) 20 m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]); 21 else 22 m[i][j]=m[i-1][j]; 23  } 24  } 25 26 for(int i=1;i<=n;i++) 27  { 28 for(int j=1;j<=c;j++) 29  { 30 cout<<m[i][j]<<' '; 31  } 32 cout<<endl; 33  } 34 35 return 0; 36 }

输出:

0 0 0 8 8 8 8 8 8 8 8 8 

0 0 0 8 8 10 10 10 10 18 18 18 

0 6 6 8 8 14 14 16 16 18 18 24 

0 6 6 9 9 14 14 17 17 19 19 24 

0 6 6 9 9 14 14 17 17 19 21 24 

2 6 8 9 11 14 16 17 19 19 21 24 

DP之大币找零钱

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N=100;
 7 void show(int m,int *v,int *b,int *ans)
 8 {
 9     if(m==0) return ;
10     ans[b[m]]++; 11 show(m-v[b[m]],v,b,ans); 12 } 13 14 int main() 15 { 16 int v[N]={1,2,5}; 17 int n=3; 18 int m=23; 19 int dp[N]; 20 int b[N]; 21 for(int i=0;i<=m;i++) dp[i]=i; 22 int min=0x3f3f3f3f; 23 for(int i=1;i<=m;i++) 24  { 25 min=0x3f3f3f3f; 26 for(int j=0;j<n;j++) 27  { 28 if(i>=v[j] && dp[i-v[j]]+1<min) 29  { 30 dp[i]=dp[i-v[j]]+1; 31 b[i]=j; 32 min=dp[i]; 33  } 34  } 35  } 36 cout<<"需要钱总量为:"<<dp[m]<<endl; 37 int num[N]; 38 memset(num,0,sizeof(num)); 39  show(m,v,b,num); 40 for(int i=0;i<n;i++) 41  { 42 cout<<"需要"<<v[i]<<"面值的钱为"<<num[i]<<" "<<"!"<<endl;; 43  } 44 return 0; 45 } 46 Download as text

 DP之石子合并

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn=100;
 8 
 9 void MinNum(int n,int p[],int m[maxn][maxn],int s[maxn][maxn])
10 {
11     for(int i=2;i<=n;i++)
12         p[i]=p[i]+p[i-1]; 13 for(int i=1;i<=n;i++) m[i][i]=0; 14 for(int len=1;len<n;len++) 15  { 16 for(int i=1;i<=n-len;i++) 17  { 18 int j=i+len; 19 m[i][j]=m[i][i]+m[i+1][j]; 20 s[i][j]=i; 21 for(int k=i;k<j;k++) 22  { 23 int t=m[i][k]+m[k+1][j]; 24 if(t<m[i][j]) 25  { 26 m[i][j]=t; 27 s[i][j]=k; 28  } 29  } 30 m[i][j]=m[i][j]+p[j]-p[i-1]; 31  } 32  } 33 } 34 35 void MaxNum(int n,int p[],int m[maxn][maxn],int s[maxn][maxn]) 36 { 37 //for(int i=2;i<=n;i++) 38 // p[i]=p[i]+p[i-1]; 39 for(int i=1;i<=n;i++) m[i][i]=0; 40 for(int len=1;len<n;len++) 41  { 42 for(int i=1;i<=n-len;i++) 43  { 44 int j=i+len; 45 m[i][j]=m[i][i]+m[i+1][j]; 46 s[i][j]=i; 47 for(int k=i;k<j;k++) 48  { 49 int t=m[i][k]+m[k+1][j]; 50 if(t>m[i][j]) 51  { 52 m[i][j]=t; 53 s[i][j]=k; 54  } 55  } 56 m[i][j]=m[i][j]+p[j]-p[i-1]; 57  } 58  } 59 } 60 61 62 void show(int i,int j,int s[maxn][maxn]) 63 { 64 if(i==j) return; 65  show(i,s[i][j],s); 66 show(s[i][j]+1,j,s); 67 cout<<"A"<<i<<"+"<<"A"<<s[i][j]<<" "; 68 cout<<"A"<<s[i][j]+1<<"+"<<"A"<<j<<endl; 69 } 70 71 int main() 72 { 73 int n; 74 int p[maxn]={0,4,4,5,9}; 75 //cin>>n; 76 n=4; 77 78 //for(int i=1;i<=n;i++) 79 // cin>>p[i]; 80 int m[maxn][maxn],s[maxn][maxn]; 81 82  MinNum(n,p,m,s); 83 cout<<m[1][n]<<endl; 84 show(1,n,s); 85  MaxNum(n,p,m,s); 86 cout<<m[1][n]<<endl; 87 show(1,n,s); 88 }

输入示例:

4

4 4 5 9

输出示例:

43

A1+A1 A2+A2

A1+A2 A3+A3

A1+A3 A4+A4

54

A3+A3 A4+A4

A2+A2 A3+A4

A1+A1 A2+A4

 

第四章贪心

贪心之最优装载

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 #include <stack>
 6 #include <queue>
 7 using namespace std;
 8 
 9 const int maxn=100;
10 
11 struct node
12 {
13     int w;
14     int num; 15 }nodes[maxn]; 16 bool cmp(node m,node n) 17 { 18 return m.w<n.w; 19 } 20 int main() 21 { 22 int c; 23 int n; 24 //cout<<"C="<<endl; 25 cin>>c; 26 //cout<<"n="<<endl; 27 cin>>n; 28 for(int i=0;i<n;i++) 29  { 30 cin>>nodes[i].w; 31 nodes[i].num=i; 32  } 33 int x[maxn]; 34 memset(x,0,sizeof(x)); 35 sort(nodes,nodes+n,cmp); 36 for(int i=0;i<n&&nodes[i].w<=c;i++) 37  { 38 x[nodes[i].num]=1; 39 c-=nodes[i].w; 40  } 41 for(int i=0;i<n;i++) 42 if(x[nodes[i].num]==1) 43 cout<<nodes[i].num<<" "; 44 cout<<endl; 45 } 46 /* 47 10 48 5 49 4 5 3 2 6 50 */

 输入示例:

10

 5

 4 5 3 2 6

输出示例:

The ans is

  The 3th   The 2th   The 0th 

 

贪心之多处最优服务次序

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <queue>
 5 #include <vector>
 6 using namespace std;
 7 
 8 const int maxn=100;
 9 
10 int x[maxn];
11 int st[maxn];
12 int su[maxn];
13 
14 int main() 15 { 16 int n; 17 int s; 18 cin>>n>>s; 19 int sum=0; 20 for(int i=0;i<n;i++) 21  { 22 cin>>x[i]; 23  } 24 sort(x,x+n); 25 int i=0,j=0; 26 while(i<n) 27  { 28 st[j]+=x[i]; 29 su[j]+=st[j]; 30 i++; 31 j++; 32 if(j==s) 33 j=0; 34  } 35 for(int i=0;i<s;i++) 36 sum+=su[i]; 37 cout<<1.0*sum/n<<endl; 38 return 0; 39 } 40 /* 41 10 2 42 56 12 1 99 1000 234 33 55 99 812 43 */

 贪心之最优服务次序

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <queue>
 5 #include <vector>
 6 using namespace std;
 7 
 8 const int maxn=100;
 9 
10 int x[maxn];
11 
12 int main()
13 {
14     int n; 15 cin>>n; 16 int sum=0; 17 for(int i=0;i<n;i++) 18  { 19 cin>>x[i]; 20  } 21 sort(x,x+n); 22 for(int i=1;i<n;i++) 23 x[i]=x[i]+x[i-1]; 24 for(int i=0;i<n;i++) 25 sum+=x[i]; 26 27 cout<<1.0*sum/n<<endl; 28 return 0; 29 } 30 /* 31 10 32 56 12 1 99 1000 234 33 55 99 812 33 */

 贪心之汽车加油问题

问题描述:

  一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。对于给定的n(n <= 5000)和k(k <= 1000)个加油站位置,编程计算最少加油次数。并证明算法能产生一个最优解。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 using namespace std;
 5 const int maxn=100;
 6 int   x[maxn];
 7 int main()
 8 {
 9     int n,k; 10 cin>>n>>k; 11 for(int i = 0;i <=k;i++){ 12 cin>>x[i]; 13 if(x[i]>n) 14  { 15 cout<<"No Solution!"<<endl; 16 return 0; 17  } 18  } 19 int sum=0,ans=0; 20 for(int i=0;i<=k;i++) 21  { 22 sum+=x[i]; 23 if(sum>n) 24  { 25 ans++; 26 sum=x[i]; 27  } 28  } 29 cout<<ans<<endl; 30 return 0; 31 }

 

输入示例:

7 7

1 2 3 4 5 1 6 6

输出示例:

4

 

贪心之Dijkstra

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <string>
  4 #include <algorithm>
  5 #include <stack>
  6 #include <cstring>
  7 #include <queue>
  8 using namespace std;
  9 
 10 const int maxn=100;
 11 int dis[maxn];
 12 const int INF=0x3f3f3f3f;
 13 int c[maxn][maxn];
 14 int pre[maxn]; 15 int n,m; 16 17 void init() 18 { 19 for(int i=1;i<=n;i++) 20 for(int j=1;j<=n;j++) 21 c[i][j]=INF; 22 for(int i=1;i<=n;i++) 23  { 24 dis[i]=INF; 25 c[i][i]=0; 26  } 27 } 28 void findpath(int t) 29 { 30 31 cout<<t; 32 if(pre[t]!=t) 33 cout<<"<-"; 34 else 35  { 36 cout<<endl; 37 return; 38  } 39  findpath(pre[t]); 40 41 } 42 43 void show() 44 { 45 for(int i=1;i<=n;i++) 46  { 47 cout<<"dis["<<i<<"]="<<dis[i]<<endl; 48 cout<<"path:"; 49  findpath(i); 50  } 51 } 52 53 void dijkstra(int v) 54 { 55 56 bool vis[maxn]; 57 for(int i=1;i<=n;i++) 58  { 59 dis[i]=c[v][i]; 60 vis[i]=false; 61 if(dis[i] == INF) 62 pre[i]=0; 63 else 64 pre[i]=v; 65  } 66 67 vis[v]=true; 68 for(int k=1;k<n;k++) 69  { 70 int min=INF; 71 int minn=v; 72 for(int i=1;i<=n;i++) 73  { 74 if(vis[i]==false && dis[i]<min) 75  { 76 min=dis[i]; 77 minn=i; 78  } 79  } 80 81 vis[minn]=true; 82 for(int i=1;i<=n;i++) 83  { 84 if(vis[i]==false && c[minn][i]<INF) 85  { 86 int t=c[minn][i]+dis[minn]; 87 if(t < dis[i]) 88  { 89 dis[i]=t; 90 pre[i]=minn; 91  } 92  } 93  } 94 95 96  } 97 } 98 99 int main() 100 { 101 cin>>n>>m; 102 int a,b,cc; 103  init(); 104 for(int i=0;i<m;i++) 105  { 106 cin>>a>>b>>cc; 107 c[a][b]=cc; 108  } 109 dijkstra(1); 110  show(); 111 return 0; 112 }

输入示例:

 5 7

 1 2 10

 1 5 100

 2 3 50

 4 5 60

 4 3 20

 1 4 30

 3 5 10

输出示例:

 dis[1]=0

 path:1

 dis[2]=10

 path:2<-1

 dis[3]=50

 path:3<-4<-1

 dis[4]=30

 path:4<-1

 dis[5]=60

 path:5<-3<-4<-1

 

贪心之prim

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 #include <stack>
 6 #include <cstring>
 7 #include <queue>
 8 using namespace std;
 9 
10 const int maxn=100;
11 int dis[maxn];
12 const int INF=0x3f3f3f3f;
13 int c[maxn][maxn];
14 int close[maxn]; 15 int n,m; 16 17 void init() 18 { 19 for(int i=1;i<=n;i++) 20 for(int j=1;j<=n;j++) 21 c[i][j]=INF; 22 for(int i=1;i<=n;i++) 23  { 24 dis[i]=INF; 25 c[i][i]=0; 26  } 27 } 28 29 30 void prim(int v) 31 { 32 int vis[maxn]; 33 memset(vis,0,sizeof(vis)); 34 for(int i=1;i<=n;i++) 35  { 36 dis[i]=c[v][i]; 37 close[i]=v; 38  } 39 40 vis[v]=1; 41 for(int len=1;len<n;len++) 42  { 43 int min=INF; 44 int minn=v; 45 for(int i=1;i<=n;i++) 46  { 47 if(vis[i]==0 && dis[i]<min) 48  { 49 min=dis[i]; 50 minn=i; 51  } 52  } 53 54 vis[minn]=1; 55 cout<<minn<<"-"<<close[minn]<<endl; 56 57 for(int i=1;i<=n;i++) 58  { 59 if(vis[i]==0 && c[i][minn]<dis[i]) 60  { 61 dis[i]=c[i][minn]; 62 close[i]=minn; 63  } 64  } 65  } 66 67 } 68 69 int main() 70 { 71 cin>>n>>m; 72 int a,b,cc; 73  init(); 74 for(int i=0;i<m;i++) 75  { 76 cin>>a>>b>>cc; 77 c[a][b]=cc; 78 c[b][a]=cc; 79  } 80 prim(1); 81 return 0; 82 }

示例输入

5 7

1 2 10

1 5 100

2 3 50

4 5 60

4 3 20

1 4 30

3 5 10

示例输出

2-1

4-1

3-4

5-3

 

贪心之kruskal

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 #include <stack>
 6 #include <cstring>
 7 #include <queue>
 8 using namespace std;
 9 
10 const int maxn=100;
11 int parent[maxn];
12 int n,m;
13 int i,j;
14 
15 struct edge 16 { 17 int u,v,w; 18 }edges[maxn]; 19 20 int find(int i){ 21 int temp; 22 for(temp = i; parent[temp] >= 0; temp = parent[temp]); 23 while(temp != i){ 24 int t = parent[i]; 25 parent[i] = temp; 26 i = t; 27  } 28 return temp; 29 } 30 31 void merge(int a,int b){ 32 int r1 = find(a); 33 int r2 = find(b); 34 parent[r1]=r2; 35 } 36 37 void kruskal(){ 38 int sumWeight = 0; 39 int num = 0; 40 int u,v; 41 for(i=1; i<=n; i++) parent[i] = -1; for(int i=0; i<m; i++) 42  { 43 u = edges[i].u; 44 v = edges[i].v; 45 46 if(find(u) != find(v)){ 47 printf("%d-%d\n", u,v); 48 sumWeight += edges[i].w; 49 num ++; 50  merge(u, v); 51  } 52  } 53 printf("weight of MST is %d \n", sumWeight); 54 } 55 56 int cmp(const edge a, const edge b){ 57 return a.w < b.w; 58 } 59 60 int main() { 61 cin>>n>>m; 62 for(i=0; i<m; i++){ 63 cin>>edges[i].u>>edges[i].v>>edges[i].w; 64  } 65 sort(edges,edges+m,cmp); 66  kruskal(); 67 68 69 return 0; 70 } 71 /* 72 测试数据: 73 7 9 74 1 2 28 75 1 6 10 76 2 3 16 77 2 7 14 78 3 4 12 79 4 5 22 80 4 7 18 81 5 6 25 82 5 7 24 83 输出: 84 1-6 85 3-4 86 2-7 87 2-3 88 4-5 89 5-6 90 weight of MST is 99 91 */

 

贪心之活动安排问题

问题描述:

  设有n个活动的集合E={1,2,……,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si<fi。如果选择了活动i,则它在时间区间[si,fi]内占用资源。若区间[si,fi]与区间[sj,fj]不相交,则称活动i与活动j是相容的。也就是说,当si>=fj或者sj>=fi时,活动i与活动j相容。活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <algorithm>
 5 #include <stack>
 6 #include <queue>
 7 using namespace std;
 8 
 9 const int maxn=100;
10 int vis[maxn];
11 struct node
12 {
13     int num; 14 int s; 15 int e; 16 /* 17 bool operator<(node b) 18 { 19 if(this->e==b.e) 20 return this->s<b.s; 21 return this->e < b.e; 22 } 23 */ 24 }nodes[maxn]; 25 bool cmp(node a,node b) 26 { 27 if(a.e<b.e) 28 return true; 29 else if(a.e==b.e && a.s<b.s) 30 return true; 31 return false; 32 } 33 34 void f(node *nodes,int n) 35 { 36 vis[0]=1; 37 int t=0; 38 for(int i=1;i<n;i++) 39  { 40 if(nodes[i].s>=nodes[t].e) 41  { 42 vis[i]=1; 43 t=i; 44  } 45  } 46 } 47 int main() 48 { 49 int n; 50 cin>>n; 51 queue<int> st; 52 for(int i=0;i<n;i++) 53  { 54 cin>>nodes[i].s>>nodes[i].e; 55 nodes[i].num=i; 56  } 57 sort(nodes,nodes+n,cmp); 58 memset(vis, 0, sizeof(vis)); 59  f(nodes,n); 60 for(int i=0;i<n;i++) 61  { 62 if(vis[i]==1) 63  st.push(nodes[i].num); 64  } 65 int len=(int)st.size(); 66 cout<<"The answer is:"<<endl; 67 for(int i=0;i<len;i++) 68  { 69 cout<<st.front()<<" "; 70  st.pop(); 71  } 72 cout<<endl; 73 return 0; 74 }

Input:

 第一行输入活动的数量n。

第二行输入2*n个整数,依次表示活动的开始时间和结束时间。

Output:

   输出要被安排的活动的编号,编号按照输入顺序从0开始编号。

输入示例:

3

1 3 2 4 3 5

输出示例:

  0 2

 

贪心之程序存储问题

问题描述:
  设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是 li,1≤i≤n。 程序存储问题要求确定这n 个程序在磁带上的一个存储方案, 使得能够在磁带上存储尽可能多的程序。 对于给定的n个程序存放在磁带上的长度,计算磁带上最多可以存储的程序数。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 using namespace std;
 5 const int maxn=100;
 6 int   x[maxn];
 7 
 8 
 9 int main()
10 {
11     int n,l; 12 cin>>n>>l; 13 for(int i = 0;i < n;i++){ 14 cin>>x[i]; 15  } 16 int sum=0,ans=0; 17 sort(x, x+n,less<int>()); 18 for(int i=0;i<n;i++) 19  { 20 sum+=x[i]; 21 if(sum<=l) 22 ans=i+1; 23  } 24 cout<<ans<<endl; 25 return 0; 26 }

 

输入示例:
6 50

2  3 13 8 80 20

输出示例:
5

 

贪心之磁盘文件最优存储问题

问题描述:
  设磁盘上有n个文件,f1,f2,…,fn,,每个文件占磁盘上1个磁道。这n个文件的检索概率分别是p1,p2,…,pn,且p1+p2+…+pn   =1。磁头从当前磁道移到被检信息磁道所需的时间可用这2个磁道之间的径向距离来度量。如果文件pi存放在第i道上,1<i<n ,则检索这n 个文件的期望时间是 ∑(Pi*Pj*d(i,j))  ,其中  d(i,j)是第i道与第j道之间的径向距离|i-j|。   

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 using namespace std;
 5 const int maxn=100;
 6 int   A[maxn];
 7 int   B[maxn];
 8 
 9 double f(int n)
10 { 11 double sum = 0,t = 0; 12 int k = (n-1)/2; 13 sort(A,A+n); 14 B[k] = A[n-1]; 15 16 for(int i = k+1;i < n;i++) 17  { 18 B[i] = A[n-2*(i-k)]; 19  } 20 for(int i = k-1;i >= 0;i--) 21  { 22 B[i] = A[n-2*(k-i)-1]; 23  } 24 for (int i = 0;i < n;i++) 25  { 26 sum += A[i]; 27 for(int j = i+1; j < n;j++) 28 t += B[i]*B[j]*(j-i); 29  } 30 return t/sum/sum; 31 } 32 33 int main() 34 { 35 int i ,n; 36 cin>>n; 37 for(i = 0;i < n;i++){ 38 cin>>A[i]; 39  } 40 double ans=f(n); 41 cout<<ans<<endl; 42 return 0; 43 }

 

输入示例:

5

33 55 22 11 9

输出示例:

0.547396

 

贪心之磁带最优存储问题

问题描述:

  设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是Li, 1<= i<= n。这n 个程序的读取概率分别是p1,p2,...,pn,且pi+p2+...+pn = 1。如果将这n 个程序按 i1,i2,....,in 的次序存放,则读取程序ir 所需的时间tr=c*(Pi1*Li2+Pi2*Li2+...+Pir*Lir)。这n 个程序的平均读取 时间为t1+t2+...+tn。 磁带最优存储问题要求确定这n 个程序在磁带上的一个存储次序,使平均读取时间达到最小。

代码:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn=100;
 6 struct node
 7 {
 8     double p,l,mul;
 9 }nodes[maxn]; 10 11 bool cmp(node a,node b) 12 { 13 return a.mul<b.mul; 14 } 15 int main() 16 { 17 int n; 18 cin>>n; 19 double sum=0; 20 for(int i=1;i<=n;i++) 21  { 22 cin>>nodes[i].l>>nodes[i].p; 23 sum+=nodes[i].p; 24  } 25 for(int i=1;i<=n;i++) 26  { 27 nodes[i].p=nodes[i].p/sum; 28 nodes[i].mul=nodes[i].l*nodes[i].p; 29  } 30 sort(nodes+1,nodes+n+1,cmp); 31 double t=0,ans=0; 32 for(int i=1;i<=n;i++) 33  { 34 t+=nodes[i].mul; 35 ans+=t; 36  } 37 cout<<ans<<endl; 38 return 0; 39 }

 

输入示例:

5

71     872

46     452

9       265

73     120

35      85

输出示例

85.6193

 

贪心之会场安排问题

问题描述:

  假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数)。

代码:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 struct node
 7 {
 8     int data;
 9     int flag;
10 }; 11 12 bool cmp(node a,node b) 13 { 14 return a.data<b.data; 15 } 16 17 int f(vector<node> v) 18 { 19 int now=0,max=0; 20 vector<node>::iterator iter=v.begin(); 21 for(;iter<v.end();iter++) 22  { 23 if(iter->flag==1) 24  { 25 now++; 26 if(now>max) 27 max=now; 28  } 29 else 30  { 31 now--; 32  } 33  } 34 return max; 35 } 36 37 int main() 38 { 39 int n; 40 vector<node> vec; 41  node t; 42 int x; 43 cin>>n; 44 for(int i=1;i<=2*n;i++) 45  { 46 cin>>x; 47 t.data=x; 48 t.flag=i%2; 49  vec.push_back(t); 50  } 51 52  sort(vec.begin(),vec.end(),cmp); 53 int ans=f(vec); 54 cout<<ans<<endl; 55 return 0; 56 }

 

输入示例:

5

1 23

12 28

25 35

27 80

36 50

输出示例:

3

 

 第五六章

分支限界法之01背包队列版

代码:

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int maxn=1000;
  9 
 10 class node
 11 {
 12 public:
 13     int id,w,p; 14 double average; 15 bool operator < (const node &a)const 16  { 17 return average>a.average; 18  }; 19 }ths[maxn]; 20 21 class bbnode 22 { 23 public: 24 bbnode *parent; 25 bool lchild; 26 bbnode(bbnode *b,bool f) 27  { 28 parent=b; 29 lchild=f; 30  }; 31 bbnode(const bbnode &a) 32  { 33 parent=a.parent; 34 lchild=a.lchild; 35  }; 36 }; 37 38 class headnode 39 { 40 public: 41 double up; 42 int cp,cw; 43 int level; 44 bbnode *bb; 45 headnode(double u,int p,int w,int l,bbnode b) 46  { 47 up=u; 48 cp=p; 49 cw=w; 50 level=l; 51 bbnode *yy=new bbnode(b.parent,b.lchild); 52 bb=yy; 53  } 54 }; 55 56 int n; 57 int c; 58 int cw; 59 int cp; 60 int bestp; 61 int best[maxn]; 62 63 bool cmpp(node a,node b) 64 { 65 return a.id<b.id; 66 } 67 double bound(int num) 68 { 69 int cleft=c-cw; 70 double p=cp; 71 while(num<=n && ths[num].w <= cleft) 72  { 73 cleft-=ths[num].w; 74 p+=ths[num].p; 75 num++; 76  } 77 if(num<=n) 78  { 79 p+=1.0*cleft/ths[num].w * ths[num].p; 80  } 81 return p; 82 } 83 84 85 void init() 86 { 87 cw=0; 88 cp=0; 89 bestp=0; 90 } 91 92 int bfs() 93 { 94 queue<headnode> que; 95 bbnode *E; 96 bbnode *beste; 97 E=0; 98 beste=0; 99 int i=1; 100 int t=bound(1); 101 while(i<=n) 102  { 103 if(cw+ths[i].w<=c) 104  { 105 if(cp+ths[i].p>bestp) 106  { 107 bestp=cp+ths[i].p; 108 beste=E; 109  } 110 que.push(headnode(t,cp+ths[i].p,cw+ths[i].w,i+1,bbnode(E,true))); 111  } 112 t=bound(i+1); 113 if(t>=bestp) 114 que.push(headnode(t,cp,cw,i+1,bbnode(E,false))); 115 headnode now=que.front(); 116  que.pop(); 117 cp=now.cp; 118 cw=now.cw; 119 i=now.level; 120 t=now.up; 121 E=now.bb; 122  } 123 if(bestp>=cp) 124 beste=E; 125 for(int j=n;j>0;j--) 126  { 127 best[j]= beste->lchild; 128 beste=beste->parent; 129  } 130 return bestp; 131 } 132 133 int main() 134 { 135 cin>>n>>c; 136 for(int i=1;i<=n;i++) 137  { 138 cin>>ths[i].p; 139 ths[i].id=i; 140  } 141 for(int i=1;i<=n;i++) 142  { 143 cin>>ths[i].w; 144 ths[i].id=i; 145 ths[i].average=1.0*ths[i].p/ths[i].w; 146  } 147 sort(ths+1,ths+n+1); 148  init(); 149 cout<<bfs()<<endl; 150 vector<node> v; 151 for(int i=1;i<=n;i++) 152 if(best[i]) 153  v.push_back(ths[i]); 154  sort(v.begin(),v.end(),cmpp); 155 for(int i=0;i<v.size();i++) 156 cout<<"The "<<v[i].id<<"th : "<<"p="<<v[i].p<<" w="<<v[i].w<<endl; 157 return 0; 158 }

 

输入示例1:

4 7

9 10 7 4

3 5 2 1

输出示例1:

20

The 1th : p=9 w=3

The 3th : p=7 w=2

The 4th : p=4 w=1

输入示例2:

6 12

8 10 6 3 7 2

4 6 2 2 5 1

输出示例2:

24

The 1th : p=8 w=4

The 2th : p=10 w=6

The 3th : p=6 w=2

 

分支限界法之01背包优先队列版

代码:

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int maxn=100;
  9 
 10 class node
 11 {
 12 public:
 13     int id,w,p; 14 double average; 15 bool operator < (const node &a)const 16  { 17 return average>a.average; 18  }; 19 }ths[maxn]; 20 21 class bbnode 22 { 23 public: 24 bbnode *parent; 25 bool lchild; 26 bbnode(bbnode *b,bool f) 27  { 28 parent=b; 29 lchild=f; 30  }; 31 }; 32 33 class headnode 34 { 35 public: 36 double up; 37 int cp,cw; 38 int level; 39 bbnode *bb; 40 headnode(double u,int p,int w,int l,bbnode b) 41  { 42 up=u; 43 cp=p; 44 cw=w; 45 level=l; 46 bbnode *yy=new bbnode(b.parent,b.lchild); 47 bb=yy; 48  } 49 bool operator < (const headnode &a)const 50  { 51 return up<a.up; 52  }; 53 }; 54 55 int n; 56 int c; 57 int cw; 58 int cp; 59 int bestp; 60 int best[maxn]; 61 62 bool cmpp(node a,node b) 63 { 64 return a.id<b.id; 65 } 66 double bound(int num) 67 { 68 int cleft=c-cw; 69 double p=cp; 70 while(num<=n && ths[num].w <= cleft) 71  { 72 cleft-=ths[num].w; 73 p+=ths[num].p; 74 num++; 75  } 76 if(num<=n) 77  { 78 p+=1.0*cleft/ths[num].w * ths[num].p; 79  } 80 return p; 81 } 82 83 84 void init() 85 { 86 cw=0; 87 cp=0; 88 bestp=0; 89 } 90 91 int bfs() 92 { 93 priority_queue<headnode> que; 94 bbnode *E; 95 E=0; 96 int i=1; 97 int t=bound(1); 98 while(i<=n) 99  { 100 if(cw+ths[i].w<=c) 101  { 102 if(cp+ths[i].p>bestp) 103 bestp=cp+ths[i].p; 104 que.push(headnode(t,cp+ths[i].p,cw+ths[i].w,i+1,bbnode(E,true))); 105  } 106 t=bound(i+1); 107 if(t>=bestp) 108 que.push(headnode(t,cp,cw,i+1,bbnode(E,false))); 109 headnode now=que.top(); 110  que.pop(); 111 cp=now.cp; 112 cw=now.cw; 113 i=now.level; 114 t=now.up; 115 E=now.bb; 116  } 117 for(int j=n;j>0;j--) 118  { 119 best[j]=E->lchild; 120 E=E->parent; 121  } 122 return cp; 123 } 124 125 int main() 126 { 127 cin>>n>>c; 128 for(int i=1;i<=n;i++) 129  { 130 cin>>ths[i].p; 131 ths[i].id=i; 132  } 133 for(int i=1;i<=n;i++) 134  { 135 cin>>ths[i].w; 136 ths[i].id=i; 137 ths[i].average=1.0*ths[i].p/ths[i].w; 138  } 139 sort(ths+1,ths+n+1); 140  init(); 141 cout<<bfs()<<endl; 142 vector<node> v; 143 for(int i=1;i<=n;i++) 144 if(best[i]) 145  v.push_back(ths[i]); 146  sort(v.begin(),v.end(),cmpp); 147 for(int i=0;i<v.size();i++) 148 cout<<"The "<<v[i].id<<"th : "<<"p="<<v[i].p<<" w="<<v[i].w<<endl; 149 return 0; 150 } 151 /* 152 4 7 153 9 10 7 4 154 3 5 2 1 155 156 6 12 157 8 10 6 3 7 2 158 4 6 2 2 5 1 159 */

输入示例1:

4 7

9 10 7 4

3 5 2 1

输出示例1:

20

The 1th : p=9 w=3

The 3th : p=7 w=2

The 4th : p=4 w=1

输入示例2:

6 12

8 10 6 3 7 2

4 6 2 2 5 1

输出示例2:

24

The 1th : p=8 w=4

The 2th : p=10 w=6

The 3th : p=6 w=2

 

回溯法之01背包

代码:

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int maxn=10;
  9 struct node
 10 {
 11     int id,w,p;
 12     double average; 13 }ths[maxn]; 14 15 bool cmp(const struct node one,const struct node other) 16 { 17 return one.average>other.average; 18 } 19 bool cmpp(const struct node one,const struct node other) 20 { 21 return one.id<other.id; 22 } 23 int n; 24 int c; 25 int cw; 26 int cp; 27 int bestp; 28 int flag[maxn]; 29 int bestf[maxn]; 30 31 double bound(int num) 32 { 33 int cleft=c-cw; 34 double p=cp; 35 while(num<=n && ths[num].w <= cleft) 36  { 37 cleft-=ths[num].w; 38 p+=ths[num].p; 39 num++; 40  } 41 if(num<=n) 42  { 43 p+=1.0*cleft/ths[num].w * ths[num].p; 44  } 45 return p; 46 } 47 48 void dfs(int num) 49 { 50 if(num>n) 51  { 52 if(bestp<cp) 53  { 54 bestp=cp; 55 for(int i=1;i<=n;i++) 56 bestf[i]=flag[i]; 57  } 58 return; 59  } 60 if(cw+ths[num].w<=c) 61  { 62 cw+=ths[num].w; 63 cp+=ths[num].p; 64 flag[num]=1; 65 dfs(num+1); 66 cw-=ths[num].w; 67 cp-=ths[num].p; 68  } 69 if(bound(num+1)>bestp) 70  { 71 flag[num]=0; 72 dfs(num+1); 73  } 74 75 } 76 77 void init() 78 { 79 cw=0; 80 cp=0; 81 bestp=0; 82 memset(flag, -1, sizeof(flag)); 83 memset(bestf, -1, sizeof(bestf)); 84 } 85 86 int main() 87 { 88 cin>>n>>c; 89 for(int i=1;i<=n;i++) 90  { 91 cin>>ths[i].p; 92 ths[i].id=i; 93  } 94 for(int i=1;i<=n;i++) 95  { 96 cin>>ths[i].w; 97 ths[i].id=i; 98 ths[i].average=1.0*ths[i].p/ths[i].w; 99  } 100 sort(ths+1,ths+n+1,cmp); 101  init(); 102 dfs(1); 103 vector<node> v; 104 cout<<bestp<<endl; 105 for(int i=1;i<=n;i++) 106 if(flag[i]==1) 107  v.push_back(ths[i]); 108  sort(v.begin(),v.end(),cmpp); 109 for(int i=0;i<v.size();i++) 110  { 111 cout<<"The "<<v[i].id<<"th :"<<"p="<<v[i].p<<" w="<<v[i].w<<endl; 112  } 113 cout<<endl; 114 return 0; 115 }

 

输入示例:

4 7

9 10 7 4

3 5 2 1

输出示例:

20

The 1th :p=9 w=3

The 3th :p=7 w=2

The 4th :p=4 w=1

 

回溯法之最小重量机器设计问题

问题描述:

  设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设 wij 是从供应商j 处购得的部件i的重量,cij 是相应的价格。试设计一个回溯算法,对于给定的机器部件重量和机器部件价格,计算总价格不超过c的最小重量机器设计。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 using namespace std;
 5 const int maxn=100;
 6 
 7 int w[maxn][maxn];
 8 int c[maxn][maxn];
 9 int best[maxn];
10 int b[maxn]; 11 int n,m,d; 12 int mi=0x3f3f3f3f; 13 int cost=0; 14 int wei=0; 15 16 void f(int num) 17 { 18 if(n==num) 19  { 20 if(wei<mi) 21  { 22 mi=wei; 23 for(int i=0;i<n;i++) 24 best[i]=b[i]+1; 25  } 26 return ; 27  } 28 29 for(int i=0;i<m;i++) 30  { 31 cost+=c[num][i]; 32 wei+=w[num][i]; 33 b[num]=i; 34 if(cost<=d && wei<mi) 35 f(num+1); 36 cost-=c[num][i]; 37 wei-=w[num][i]; 38  } 39 40 } 41 42 int main() 43 { 44 cin>>n>>m>>d; 45 for(int i=0;i<n;i++) 46 for(int j=0;j<m;j++) 47 cin>>c[i][j]; 48 for(int i=0;i<n;i++) 49 for(int j=0;j<m;j++) 50 cin>>w[i][j]; 51 f(0); 52 cout<<mi<<endl; 53 for(int i=0;i<n;i++) 54 cout<<best[i]<<" "; 55 cout<<endl; 56 57 }

 

输入示例:

3 3 4
1 2 3
3 2 1
2 2 2
1 2 3
3 2 1
2 2 2

输出示例:

4
1 3 1

 

转载于:https://www.cnblogs.com/wangxuelin/p/9108638.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值