码迷,mamicode.com
首页 > 其他好文 > 详细

51nod1625 夹克爷发红包(贪心+dfs)

时间:2018-07-08 17:17:05      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:有一个   fine   names   题目   超过   int   scanf   改变   取值   

题目链接: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\n",ans);
    return 0;
}

 



51nod1625 夹克爷发红包(贪心+dfs)

标签:有一个   fine   names   题目   超过   int   scanf   改变   取值   

原文地址:https://www.cnblogs.com/xiongtao/p/9280536.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!