输入数据有n+1行: 第一行为工程师人数n(1 ≤ n ≤ 6) 接下来的n行,每行一个字符串表示第i(1 ≤ i ≤ n)个人能够胜任的工作(字符串不一定等长的)
输出一个整数,表示有多少种不同的工作安排方案
6 012345 012345 012345 012345 012345 012345
720
//利用回溯法求解.//题意有两个地方没说清楚:1、一个人只能做一项工程,而不能分饰两角;// 2、有几个工程师,每个工程师有一个工作即满足题意,不用6项工作全部都要有人做。//前一个人选了哪项工作,直接影响后一个人的选择余地。//所以需要用一个set记录在当前这个人选择之前,前面那些人已经选了的工作,进而他只能选除set中已有剩下的工作。//当考察完最后一个人,情况数+1(递归出口),证明是满足题意的方案。下面是代码import java.util.HashSet; import java.util.Scanner; //网易:工程师与项目的匹配 public class Wangyi_WorkAndWorker { private static int cases = 0; public static void main(String[] args) { //读取输入 Scanner in = new Scanner(System.in); int n = in.nextInt(); String[] ables = new String[n]; for(int i = 0; i < n; i++) ables[i] = in.next(); //计算 backtracing(ables, 0, new HashSet<Integer>()); System.out.println(cases); in.close(); } public static void backtracing(String[] ables, int index, HashSet<Integer> set){ if(index >= ables.length){ cases++; return; } String able = ables[index]; for(int i = 0; i < able.length(); i++){ int work = able.charAt(i) - '0'; if(!set.contains(work)) { set.add(work); backtracing(ables, index + 1, set); set.remove(work); } } } }
package go.jacob.day914;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
/**
 * [编程题]工作安排
 * 
 * @author Jacob 
 * 利用回溯法求解
 * 
 * 需要说明的是:
 * 不必每一项工作都有人做,只要每个人都分配到工作即可
 * 
 */
public class Demo1 {
	public static int count = 0;
	public static Set<Integer> set;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		String[] strs = new String[n];
		set = new HashSet<Integer>();
		for (int i = 0; i < n; i++) {
			strs[i] = sc.next();
		}
		for (int i = 0; i < 6; i++) {
			set.add(i);
		}
		solve(strs, 0);
		System.out.println(count);
		sc.close();
	}
	private static void solve(String[] strs, int k) {
		if (k == strs.length) {
			count++;
			return;
		}
		for (char c : strs[k].toCharArray()) {
			if (set.contains(c - '0')) {
				set.remove(c - '0');
				solve(strs, k + 1);
				set.add(c - '0');
			}
		}
	}
}
 n=int(raw_input()) joblist=[] for i in range(n): joblist.append(raw_input().strip()) def work_assign(i,joblist,res): result=0 for k in joblist[i]: if k not in res: if i==n-1: result+=1 else: result+=work_assign(i+1,joblist,res+[k]) return result print(work_assign(0,joblist,[])) 跟背包放法问题相似
import java.util.Scanner;
public class Main {
    static int count = 0;
    static int n = 0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        count = 0;
        n = in.nextInt();
        String[] ability = new String[n];
        for (int i = 0; i < n; i++) {
            ability[i] = in.next();
        }
        generate(ability,0, 0);
        System.out.println(count);
    }
    private static void generate(String[] ability,int peopleNumber, int current) {
        String s=ability[peopleNumber];
        if (peopleNumber == n-1) {
            for(int i=0;i<s.length();i++){
                int job=s.charAt(i)-'0';
                if ((current&(1<<job))==0){
                    count++;
                }
            }
        } else {
            for(int i=0;i<s.length();i++){
                int job=s.charAt(i)-'0';
                if ((current&(1<<job))==0){
                    generate(ability,peopleNumber+1,current|(1<<job));
                }
            }
        }
    }
}
/*
这道题目题意有点模糊
其实意思是:
1、所有工程师都必须有事可做,且只能做一件事情。
2、不必所有事都要做。	 
下面的代码就是实现上述功能 
*/
#include <iostream>
using namespace std;
#include<string.h>
#define N 6
int sum = 0;
int b[N] = {0}; //记录工作是否被做过 
int main(int argc, char *argv[])
{
	void fun(string a[], int m, int k);
	string a[N]; 
	int k;
	cin>>k;
	for(int i = 0; i < k; i++)
		cin>>a[i];
	
	fun(a, 0, k);
	cout<<sum<<endl;
	return 0;
}
//回溯法求解 
void fun(string a[], int m, int k) 
{
	if (m == k) {
		sum++;
	}	
	else {
		for (int j = 0; j < a[m].size(); j++) {
			int temp = (int)(a[m][j] - '0');
			if (b[temp] == 0) {
				b[temp] = 1;
				fun(a, m + 1, k);
				b[temp] = 0;
			}		 
		}
	}
}
                                                                                    #include <iostream>
#include <vector>
#include<set>
#include<string>
using namespace std;
 
void backtracing(string str[], int index,int n, set<int> sev);
 
int cases = 0;
int main()
{
    int n = 0;
    cin >> n;
    string str[6];
    int index = 0;
    set<int> sev ;
    for (int i = 0; i < n; ++i)
    {
        cin>>str[i];
    }
    backtracing(str, 0, n, sev);
    cout << cases << endl;
}
void backtracing(string str[], int index,int n, set<int> sev)
{
    if (index == n)
    {
        ++cases;
        return;
    }
    string str0 = str[index];
    for (int i = 0; i < str0.length(); i++){
 
        int work = str0[i] - '0';
        if (sev.find(work)==sev.end()) {
            sev.insert(work);
            backtracing(str, index + 1,n, sev);
            sev.erase(work);
        }
    }
} n = int(input()) canDo = [input() for _ in range(n)] done = [False] * 6 def solve(i): if i == n: return 1 res = 0 for k in range(6): if not done[k] and (str(k) in canDo[i]): done[k] = True res += solve(i+1) done[k] = False return res print(solve(0))
#include <iostream>
#include <vector>
using namespace std;
 
int queenProblem(const vector<vector<bool>> &a, vector<bool> &mask, int id)
{
    int i, sum = 0;
    for(i = 0; i < 6; i++)
        if (a[id][i] && mask[i])
        {
            if (id == 0)
                sum += 1;
            else
            {
                mask[i] = false;
                sum += queenProblem(a, mask, id - 1);
                mask[i] = true;
            }
        }
    return sum;
}
 
 
int main()
{
    int n, i, j;
    cin >> n;
    vector<vector<bool>> a(n, vector<bool>(6, false));
    string str;
    for (i = 0; i < n; i++)
    {
        cin >> str;
        for (j = 0; j < str.length(); j++)
            a[i][str[j] - '0'] = true;
    }
    vector<bool> mask(6, true);
    cout << queenProblem(a, mask, n - 1) << endl;;
    return 0;
} 类似于八皇后问题,准确的说更像是n堡垒问题?
                                                                                    #include <bits/stdc++.h>
using namespace std;
int n;
int ans;
vector<vector<int>> able(10, vector<int>(0));
int work[10];
void init()
{
    for (int i = 0; i < 10; i++)
        able[i].clear();
}
void dfs(int i)
{
    if (i == n + 1) 
    {
        ans++;
        return;
    }
    else
    {
        int len = able[i].size();
        for (int j = 0; j < len; j++)
        {
            int v = able[i][j];
            if (!work[v])
            {
                work[v] = 1;
                dfs(i + 1);
                work[v] = 0;
            }
        }
    }
}
int main()
{
    while (cin >> n)
    {
        ans = 0;
        init();
        memset(work, sizeof(work), 0);
        string s;
        for (int i = 1; i <= n; i++)
        {
            cin >> s;
            for (int j = 0; j < s.size(); j++)
                able[i].push_back(s[j] - '0');
        }
        dfs(1);
        cout << ans << endl;
    }
    system("pause");
    return 0;
} import sys class Solution: def get_work_assignment(self, arr): count = [0] for i in arr[0]: self.process(arr, i, 1, count) print(count[0]) def process(self, arr, path, level, count): if level == len(arr): count[0] += 1 return for i in arr[level]: if i not in path: self.process(arr, path+i, level+1, count) if __name__ == '__main__': n = int(sys.stdin.readline()) args = list() for _ in range(n): args.append(sys.stdin.readline().strip()) solution = Solution() solution.get_work_assignment(args)
import java.util.Scanner;
/*
 * 非常典型的dfs解题方法,然后使用visited防止元素重复访问
 * */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            n = scanner.nextInt();
            String[] strs = new String[n];
            for (int i = 0; i < n; i++) {
                strs[i] = scanner.next();
            }
//            有六项任务
            boolean[] used = new boolean[6];
            dfs(used, strs, 0);
            System.out.println(count);
        }
    }
    private static int count = 0;
    private static int n = 0;
    private static void dfs(boolean[] visited, String[] strings, int cur) {
        if (cur == n) {
            count++;
            return;
        }
        String curS = strings[cur];
        for (int i = 0; i < curS.length(); i++) {
            int tmp = curS.charAt(i) - '0';
            if (!visited[tmp]) {
                visited[tmp] = true;
                dfs(visited, strings, cur + 1);
                visited[tmp] = false;
            }
        }
    }
}
//答案是我抄的
//回溯法
import java.util.HashSet;
import java.util.Scanner;
public class Main{
    
    private static int result = 0;   //需要将result作为全局变量,result为情况种类
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        /*
         * 6
012345 012345 012345 012345 012345 012345
         */
        
        /*
         * 使用回溯法,回溯法利用递归特性,将路径看做栈,当前n-1个都符合情况,在n的时候不符合情况的时候
         * 回溯到n-2的时候,重新定义n-1递归
         */
        
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        String [] array = new String [n];    // 输入,012345存入array[i]中
        for(int i = 0;i < n;i++){
            array[i] = scanner.next();
        }
        //computing
        backtracing(array,0,new HashSet<>()); //创建新的hashset保存已经被选了的工作
        System.out.println(result);
    }
    
    public static void backtracing(String [] array,int index,HashSet<Integer> set){
        if(index >= array.length){            //递归出口,找到一个可行解,则result++再return
            result++;
            System.out.println("array,length = "+array.length);
            return;
        }
        
        String arraynew = array[index];
        for(int i = 0;i < arraynew.length();i++){
            int work = arraynew.charAt(i) - '0';
            if(!set.contains(work)){
                set.add(work);
                backtracing(array, index+1, set);
                set.remove(work);
            }
        }
    }
}
 #include<iostream>#include<vector>#include<algorithm>#include<string>using namespace std;intplace(vector<vector<int>>& v, intstart, vector<int>& visited);intmain() {intn;cin >> n;vector<vector<int>> v;for(inti = 0; i < n; ++i) {vector<int> vec;string s;cin >> s;for(intj = 0; j < s.size(); ++j) {vec.push_back(s[j] - '0');}v.push_back(vec);}vector<int> visited(6, 0);intres = place(v, 0, visited);cout << res << endl;}intplace(vector<vector<int>>& v, intstart, vector<int>& visited) {if(start == v.size()) {return1;}intres = 0;for(inti = 0; i < v[start].size(); ++i) {intnum = v[start][i];if(visited[num] == 0) {visited[num] = 1;res += place(v, start + 1, visited);visited[num] = 0;}}returnres;}
import java.util.*;
public class Main
{
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        in.nextLine();
        String[] skills=new String[n];
        for(int i=0;i<n;i++)
        {
            skills[i]=in.nextLine();
        }
        
        HashSet<Character> done=new HashSet<Character>();
        System.out.println(getTaskAllocationNum(skills,0,done));
    }
    
    public static int getTaskAllocationNum(String[] skills,int index,HashSet<Character> done)
    {
        if(index==skills.length)
        {
            return 1;
        }
        else
        {
            int num=0;
            for(int i=0;i<skills[index].length();i++)
            {
                if(!done.contains(skills[index].charAt(i)))
                {
                    done.add(skills[index].charAt(i));
                    num+=getTaskAllocationNum(skills,index+1,done);
                    done.remove(skills[index].charAt(i));
                }
            }
            return num;
        }
    }
} #include <iostream>
#include <vector>
#include <string>
 
using namespace std;
 
void dfs(vector<string>& person, vector<int>& task, int taskcount, int& res, int next){
    if(taskcount==person.size()){
        res++;
        return;
    }
    int i=next,j,n=person.size();
    int m = person[i].size();
    for(j=0;j<m;j++){
        if(task[person[i][j]-'0']==0){
            task[person[i][j]-'0']=1;
            dfs(person,task,taskcount+1,res,next+1);
            task[person[i][j]-'0']=0;
        }
    }
}
 
int main(){
    int n;
    cin>>n;
    string s="";
    vector<string> person(n,s);
    vector<int> task(6,0);
    int res=0;
    for(int i=0;i<n;i++){
        cin>>s;
        person[i]=s;
    }
    dfs(person,task,0,res,0);
    cout<<res<<endl;
    return 0;
} package Wangyi2017;
import java.util.Scanner;
public class WorkArrange {
	public static int res=0;
	public static int [] a=new int[6];
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext())
		{
			int n=sc.nextInt();
			String []arr=new String[n];
			sc.nextLine();
			for(int i=0;i<n;i++)
			{
				arr[i]=sc.nextLine();
			}
			arrange(arr,n);
			System.out.println(res);
			res=0;
		}
		sc.close();
	}
	public static void arrange(String []arr,int n)
	{		
		if(n==0)
		{
			res++;			
			return;
		}
		for(int i=0;i<arr[n-1].length();i++)
		{
			if(a[arr[n-1].charAt(i)-'0']!=0)
			{
				continue;
			}
			else {				
				a[arr[n-1].charAt(i)-'0']=1;
				arrange(arr, n-1);
				a[arr[n-1].charAt(i)-'0']=0;
			}
		}		
	}
}