zoukankan      html  css  js  c++  java
  • 导游

    宁波市的中小学生们在镇海中学参加程序设计比赛之余,热情的主办方邀请同学们参观镇海中学内的各处景点,已知镇海中学内共有n处景点。现在有n位该校的学生志愿承担导游和讲解任务。每个学生志愿者对各个景点的熟悉程度是不同的,如何将n位导游分配至n处景点,使得总的熟悉程度最大呢?要求每个景点处都有一个学生导游。

    输入
    输入文件daoyou.in中有若干行:

    第一行只有一个正整数n,表示有n个景点和n个学生导游。

    第二行至第n+1行共n行,每行有n个以空格分隔的正整数。第i+1行的第j个数k(1≤k≤1000),表示第i个学生导游对景点j的熟悉程度为k。

    输出
    输出文件daoyou.out只有一行,该行只有一个正整数,表示求得的熟悉程度之和的最大值。

    样例输入
    3 10 6 8 9 2 3 1 7 2

    样例输出
    24

    数据范围
    50%的数据,1≤n≤9。

    100%的数据,1≤n≤17。

    纯粹的暴力,过不了的

    #include <bits/stdc++.h>
    using namespace std;
     
    struct stu
    {
        int a[20];
    }s[20];
     
    int n,maximum = 0;
    bool vis[20] = {false};
     
    void dfs(int depth, int sum){
        if(depth >= n){
            if(sum > maximum)
                maximum = sum;
            return;
        }
     
        for (int i = 0; i < n; ++i)
        {
            if(!vis[i]){
                vis[i] = true;
                dfs(depth+1, sum + s[i].a[depth]);
                vis[i] = false;
            }
        }
    }
     
    int main()
    {
        scanf("%d",&n);
        for (int i = 0; i < n; ++i){
            for (int j = 0; j < n; ++j){
                scanf("%d",&s[i].a[j]);
            }
        }
     
        dfs(0,0);
        printf("%d
    ", maximum);
     
        return 0;
    }
    

      加下剪枝

    #include <bits/stdc++.h>
    using namespace std;
      
    int n;
    int s[20];
    int a[20][20];
    int vis[20];
    int ans;
      
    void dfs(int step, int sum){
        if(step == n){
            ans = max(ans,sum);
            return;
        }
        if(sum + s[step] <= ans)
            return;
        for (int i = 0; i < n; ++i) 
    	{
            if(!vis[i]) 
    		{
                vis[i] = 1;
                dfs(step + 1, sum + a[step][i]);
                vis[i] = 0;
            }
        }
    }
      
    int main()
    {
        cin >> n;
        
        for (int i = 0; i < n; ++i) 
    	{
    		int m = 0;
            for (int j = 0; j < n; ++j) 
    		{
                cin >> a[i][j];
                m = max(m,a[i][j]); //取出每一行的最大值 
            }
            s[i] = m;
        }
        for (int i = n-1; i >= 0; --i) 
    	{
            s[i] += s[i+1];
            //s[i]代表从第i行到第N行,每行取最大值时,可以取到的最优值 
        }
        dfs(0,0);
        cout << ans << endl;
      
        return 0;
    }
    

      

     

      正解为状态压缩DP.时间复杂度为O(N*2^N)

    #include <bits/stdc++.h>
    using namespace std;
    int n,a[20][20],f[20][250000];
    int main()
    {
        scanf("%d",&n);
        for (int i=1; i<=n; i++)         
        for (int j=1; j<=n; j++)      
        scanf("%d",&a[i][j]);
        memset(f,128,sizeof(f));
        f[0][0]=0;
        for (int i=1; i<=n; i++)         
        for (int j=0; j<=(1<<n)-1; j++)         
        if (f[i-1][j]>=0)         
        {
                    for (int x=0; x<=n-1; x++)             
                    if (((1<<x)&j)==0)              
                    f[i][j|(1<<x)]=max(f[i][j|(1<<x)],f[i-1][j]+a[i][x+1]);
        }
        printf("%d
    ",f[n][(1<<n)-1]);
        return 0;
    }
    
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
     
    const int maxn=17;
    int a[maxn+1][maxn+1];
    int dp[1<<maxn];
    int n,num;
     
    int main()
    {
    	cin>>n;
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			cin>>a[i][j];
    	memset(dp,0,sizeof(dp));
    	for (int sta=1;sta<=(1<<n)-1;sta++)
    	{
    		num=0;
    		for (int j=0;j<n;j++)
    			if ((sta&(1<<j))>0) num++;
    		for (int i=1;i<=n;i++)
    			if (sta&(1<<(i-1)))
    				dp[sta]=max(dp[sta],dp[sta-(sta&(1<<(i-1)))]+a[num][i]);
    	}
    	cout<<dp[(1<<n)-1];	
    	return 0;
    }
    

      

      

    有兴趣的可以写下KM算法

  • 相关阅读:
    线程
    unix架构
    Unix命令
    可重入函数reentrant function
    Eclipse 中 program arguments 与 VM arguments 的区别
    Java中Generics的使用
    Java的Reflection机制
    Java按值传递、按引用传递
    Java label
    LeetCode Merge Intervals
  • 原文地址:https://www.cnblogs.com/cutemush/p/13543869.html
Copyright © 2011-2022 走看看