题解

描述

子集和问题的一个实例为〈S,t〉。其中,S={ x1 , x2 ,…,xn }是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得:SUM(S1) = c

试设计一个解子集和问题的回溯法。

对于给定的正整数的集合S={ x1 , x2 ,…,xn }和正整数c,计算S 的一个子集S1,使得:SUM(S1)=c。

Input

输入数据的第1 行有2 个正整数n 和c(n≤10000,c≤10000000),n 表示S 的大小,c是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。

Output

将子集和问题的解输出。当问题无解时,输出“No Solution!”。

复制代码
 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstdlib>
 4 using namespace std;    
 5 int n,a[10000000],b[10000000],m,i,k=1,s=0;
 6 bool f[10000000];
 7 void print(int k)
 8 {
 9     for (i=1;i<=k;++i)cout<<b[i]<<" ";
10     exit(0);
11 } 
12 
13 void gcd(int k,int s,int m)
14 {   
15     int i;
16     if (s>m)return;
17     if (k>n){cout<<"No Solution!";exit(0);}
18     for (i=1;i<=n;++i)
19     if (f[i])
20     {
21         f[i]=false;
22         s=s+a[i];
23         b[k]=a[i];
24         if (s==m){print(k);}
25           else gcd(k+1,s,m);
26         s=s-a[i];
27             f[i]=true;
28             b[k]=0;
29     }
30     
31     return ;
32 }
33 
34 
35 int main()
36 {
37     cin>>n;    cin>>m;
38     for (i=1;i<=n;++i)cin>>a[i];
39     for (i=1;i<=n;++i)f[i]=true;
40     gcd(k,s,m);
41     return 0;
42 }
复制代码

2、 描述:

设有n件工作分配给n个人。为第i个人分配工作j所需的费用为c[i][j] 。试设计一个算法,计算最佳工作分配方案,为每一个人都分配1 件不同的工作,并使总费用达到最小。

数据输入 :

第一行一个正整数n(1<=n<=20),接下来的n 行,每行n 个数,表示工作费用 。
结果输出:
输出有m行,每行输出最小总费用。

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int tab[21][21],n,best=100000,r[21];
 4 int compute(int k)
 5 {
 6     int temp=0,i;
 7     for(i=1;i<=k;i++)
 8         temp+=tab[i][r[i]];
 9     return temp;
10 }
11 void search(int k)
12 {
13     if(k==n)
14     {
15         int temp=compute(n);
16         if(temp<best)
17             best=temp;
18         return;
19     }
20     for(int i=k;i<=n;i++)
21     {
22         swap(r[i],r[k]);
23         if(compute(k) < best)
24             search(k+1);
25         swap(r[i],r[k]);
26     }
27 }
28 
29 int main()
30 {
31     int i,j;
32     cin>>n;
33         for(i=1;i<=n;i++)
34             for(j=1;j<=n;j++)
35                 cin>>tab[i][j];
36         for(i=1;i<=n;i++)
37             r[i]=i;
38         //best=INT_MAX;
39         search(1);
40         cout<<best<<endl;
41     return 0;
42 }
复制代码

 3、【问题描述】

从三个元素的集合[A,B,C]中选取元素生成一个N个字符组成的序列,使得没有两个相邻字的子序列(子序列长度=2)相同。例:N = 5时ABCBA是合格的,而序列ABCBC与ABABC是不合格的,因为其中子序列BC,AB是相同的。 对于由键盘输入的N(1<=N<=12),求出满足条件的N个字符的所有序列和其总数。

【输入样例】 4

【输出样例】 72

复制代码
 1 #include<iostream>
 2 #include<cstdlib>
 3 using namespace std;
 4 int n,a[100],s;
 5 void go(int x)
 6 {
 7     if (x>n) 
 8     {
 9         s++;
10         return;
11         }
12     int i;
13     for (i=1;i<=3;i++)
14     if (a[x-3]*10+a[x-2]!=a[x-1]*10+i)
15     {
16         a[x]=i;
17         go(x+1);
18         }
19 }
20 int main()
21 {
22     cin>>n;
23     if (n<=2)
24     {
25         if (n==1) cout<<3;
26         else cout<<9;
27         cout<<endl;
28         exit(0);
29         }
30     s=0;
31     int i,j,k;
32     for (i=1;i<=3;i++)
33       for (j=1;j<=3;j++)
34         for (k=1;k<=3;k++)
35       {
36             a[1]=i; a[2]=j; a[3]=k;
37             go(4);
38             }
39     cout<<s<<endl;
40     return 0;
41 }
复制代码

 

posted @   jetaim  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示