zoukankan      html  css  js  c++  java
  • 勇敢的妞妞 ( 状压 + 思维)

    题目链接:https://ac.nowcoder.com/acm/contest/315/E

    具体思路:首先,对于当m>=5的时候,我们可以直接选取每一列中最大的那一个,直接相加就可以.

    然后对于当m<5的时候,我们可以采取状压的思路,因为列数只有5,所以最多只有32中情况,所以将每种情况的最优的那一个选取出来,然后再用搜索的方式将最优解再找出来.

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    # define ll long long
    const int maxn = 10000+100;
    # define inf 0x3f3f3f3f
    const int mod = 1e9;
    int a[maxn][10];
    int viss[maxn];
    vector<int>q;
    int n,m;
    int ans=0;
    void dfs(int dt,int tmp[],int num)
    {
        if(num==m)
        {
            int t=0;
            for(int i=0; i<5; i++)
            {
                t+=tmp[i];
            }
            ans=max(ans,t);
            return ;
        }
        int len=q.size();
        for(int i=dt; i<len; i++)
        {
            int tmps[10];
            memset(tmps,0,sizeof(tmps));
            for(int j=0; j<5; j++)
            {
                tmps[j]=max(tmp[j],a[q[i]][j]);
            }
            dfs(i,tmps,num+1);
        }
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<5; j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        if(m>=5)
        {
            int sum=0;
            for(int i=0; i<5; i++)
            {
                int maxx=0;
                for(int j=1; j<=n; j++)
                {
                    maxx=max(maxx,a[j][i]);
                }
                sum+=maxx;
            }
            printf("%d
    ",sum);
            return 0;
        }
        else
        {
            int maxstate=(1<<5)-1;
            for(int i=1; i<=maxstate; i++)
            {
                int vis[10];
                memset(vis,0,sizeof(vis));
                for(int j=0; j<5; j++)
                {
                    if(((1<<j)&i)!=0)
                    {
                        vis[j]=1;
                    }
                }
                int maxx=0,id;
                for(int j=1; j<=n; j++)
                {
                    int sum=0;
                    for(int k=0; k<5; k++)
                    {
                        if(vis[k])
                        {
                            sum+=a[j][k];
                        }
                    }
                    if(sum>maxx)
                    {
                        maxx=sum;
                        id=j;
                    }
                }
                if(viss[id])continue;
                q.push_back(id);
            }
            int ww[10];
            memset(ww,0,sizeof(ww));
            dfs(0,ww,0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    UWP AppConnection.
    Qt 多线程使用moveToThread
    C#综合细说进程、应用程序域与上下文
    C++ std::function
    商品价格加价区间的实现(策略模式)
    学习web前端三个月感悟
    triangle leetcode C++
    Linux入门视频
    轻松学习Linux之进程监视与管理
    阻止缓冲区溢出攻击
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262775.html
Copyright © 2011-2022 走看看