51nod 1625 贪心/思维

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

1625 夹克爷发红包

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
在公司年会上,做为互联网巨头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
还有这种操作,贪心半天发现会有后效性,后来看题解说枚举行状态我才明白过来= =,将行状态固定之后再去贪心的更新列状态找到最大值就方便多了。
万恶的bug竟是因为我用s1记录已经发过了几行红包,更新列的时候直接 (int j=s1;j<=k;++j) ,特喵的相当于赠送了一个红包,检查了半天我也是服气!
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL  long long
 4 LL e[15][205];
 5 LL r[15];
 6 LL o[205];
 7 int main()
 8 {
 9     LL n,m,x,k,i,j;
10     cin>>n>>m>>x>>k;
11     for(i=1;i<=n;++i)
12     {
13         for(j=1;j<=m;++j)
14         {
15             scanf("%lld",&e[i][j]);
16             r[i]+=e[i][j];
17         }
18     }
19     for(i=1;i<=m;++i)
20         for(j=1;j<=n;++j)
21     o[i]+=e[j][i];
22     LL ans=0;
23     for(i=0;i<(1<<(n));++i)
24     {
25         LL s1=0,s2=0;
26         for(j=1;j<=n;++j)
27         {
28             if(i&(1<<(j-1))){
29                 s1++;
30                 s2+=x*m;
31             }
32             else s2+=r[j];
33         }
34         if(s1>k) continue;
35         priority_queue<LL,vector<LL>,greater<LL> >q;
36 
37         for(j=1;j<=m;++j)
38         {
39             LL fro=o[j];
40             for(LL c=1;c<=n;++c)
41                 if(i&(1<<(c-1))) {fro+=(x-e[c][j]);}
42             q.push(fro);
43         }
44         for(j=s1+1;j<=k;++j)
45         {
46             LL t=q.top();
47             if(t>x*n||q.empty()) break;
48             else{
49                 s2+=(x*n-t);
50                 q.pop();
51             }
52 
53         }
54         ans=max(ans,s2);
55 
56     }
57     cout<<ans<<endl;
58     return 0;
59 }
60 /*
61 附上一组数据
62 3 3 30 2
63 10 10 10
64 1 1 99
65 20 20 99
66 388
67 */
原文地址:https://www.cnblogs.com/zzqc/p/7459905.html