zoukankan      html  css  js  c++  java
  • 51nod1625 夹克爷发红包(贪心+dfs)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1625

    在公司年会上,做为互联网巨头51nod掌门人的夹克老爷当然不会放过任何发红包的机会。
     
    现场有n排m列观众,夹克老爷会为每一名观众送出普通现金红包,每个红包内金额随机。
     
    接下来,夹克老爷又送出最多k组高级红包,每高级红包会同时给一排或一列的人派发 ,每高级红包的金额皆为x。
     
    派发高级红包时,普通红包将会强制收回。同时,每个人只能得到一个高级红包。(好小气!)
     
    现在求一种派发高级红包的策略,使得现场观众获得的红包总金额最大。
    Input
    第一行为n, m, x, k四个整数。
    
    1 <= n <= 10, 1 <= m <= 200
    1 <= x <= 10^9,0 <= k <= n + m
    
    接下来为一个n * m的矩阵,代表每个观众获得的普通红包的金额。普通红包的金额取值范围为1 <= y <= 10^9
    Output
    输出一个整数,代表现场观众能获得的最大红包总金额
    Input示例
    3 4 1 5
    10 5 7 2
    10 5 10 8
    3 9 5 4
    Output示例
    78

    题目意思就是,一个n*m的矩阵的人,每个人都有一个普通的红包,现在有一种x元的高级红包,有k次机会发高级红包,
    只能一行或一列发,并且得到高级红包的人将没收普通红包。问最多可以发出去多少红包总金额。(给的样例也是醉了,
    居然有高级红包还没有普通红包多的)
    题目思路:有dfs搜索每行要高级红包或者不要的所以情况,在解决列变化的情况。
    代码如下:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    ll ans,n,m,x,k;
    ll a[15][250],b[15][250],vis[250],all[250];
    
    void solve()
    {
        ll used=0;//已经使用了几次高级红包 
        for(int i=0;i<n;i++)
            if(vis[i])
                used++;
        for(int i=0;i<n;i++)//记录变化每个人金钱数 
            for(int j=0;j<m;j++) 
                if(vis[i])//是高级红包就要改变原来的值 
                    b[i][j]=x;
                else
                    b[i][j]=a[i][j];
        ll sum=0;//记录全部总金钱数 
        memset(all,0,sizeof(all));//all记录改变后,每列总金钱数 
        for(int j=0;j<m;j++)
        { 
            for(int i=0;i<n;i++) 
            {
                all[j]+=b[i][j]; 
                sum+=b[i][j];
            }
        }
        int kk=k-used;//剩下的使用高级红包的次数 
        sort(all,all+m);//排序,用来查找列金额是否有小于使用高级红包的 
        for(int i=0;i<m;i++)
        {
            if(all[i]<n*x&&kk>0)//可以对此时的i列用高级红包 
            {
                sum-=all[i];
                sum+=n*x;
                kk--;
            }
        }
        ans=max(ans,sum);//记录最大值 
    }
    
    void dfs(int h,int sum)
    {
        if(sum>k)//超过k次 
            return ;
        if(h==n)//行数都考虑完了 
            solve();
        else
        {
            vis[h]=1;//当前h行要高级红包 
            dfs(h+1,sum+1);
            vis[h]=0;//不要高级红包 
            dfs(h+1,sum);
        }
    }
    int main()
    {
        scanf("%lld%lld%lld%lld",&n,&m,&x,&k);
        memset(vis,0,sizeof(vis));
        ans=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                scanf("%lld",&a[i][j]);
        dfs(0,0);
        printf("%lld
    ",ans);
        return 0;
    }
    
    
    


  • 相关阅读:
    RabbitMQ详解
    嵌入式开发学习(10)<汇编写启动代码之设置栈、调用c语言、开关看门狗和开关iCache>
    嵌入式开发学习(8)<一步一步点亮LED灯>
    gcc编译神器之makefile
    嵌入式开发学习(6)<S5PV210开发板刷系统那点破事儿之二>
    嵌入式开发学习(5)<S5PV210开发板刷系统那点破事儿之一>
    嵌入式开发学习(4)<ARM汇编指令集详解>
    嵌入式开发学习(3)<ARM汇编指令集语法>
    嵌入式开发学习(2)<S5PV210启动过程详解>
    嵌入式开发学习(1)<ARM体系结构>
  • 原文地址:https://www.cnblogs.com/xiongtao/p/9280536.html
Copyright © 2011-2022 走看看