您的位置:首页 > 其它

51nod 1625夹克爷发红包(贪心+枚举)

2017-10-21 10:14 253 查看
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

题解:本来一开始以为是一旦单纯的比较麻烦的贪心题:每次选择行或者列中收益最大的一列,然后对列或者行信息进行更新。但是有一组数据总是过不了,于是我就开始怀疑算法的正确性,其实没有充分的理由说明这样的贪心是正确的,因为行列直接的彼此影响还是存在的。如果说贪心会错的,那么枚举一定不会错,由于行只有10行,所以枚举行的所有状态,其次在对列进行贪心,显然这样的算法是正确的,而且复杂度不会超时。

对于我这样的菜鸟,感觉这个题还是很考验debug能力的。

注意点:

1.建议全部的变量数组都开long long

2.dfs的退栈处理

代码:

#include<iostream>
#include<fstream>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
#include<utility>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1e4+5;
const int mod = 1e9+7;
const int INF = 1<<30;
const ll llINF = 1e18+999;

ll n, m, x, k, ans, in[10][200], row[10], tcol[200], col[200];//arr表示每一列或着行替换为
void init( )
{
for(int i=0; i<n; i++)
{
ll sum = 0;
for(int j=0; j<m; j++)
sum += in[i][j];
row[i] = x*m-sum;
}
for(int i=0; i<m; i++)
{
ll sum = 0;
for(int j=0; j<n; j++)
sum += in[j][i];
col[i] = x*n-sum;
}
}
void dfs(int index, int r, ll sum)
{
if(index == n)//行已经枚举完毕了,此时对列进行贪心
{
memcpy(tcol, col, sizeof(col));
sort(tcol, tcol+m);
for(int i=0; i<r&&i<m&&tcol[m-i-1]>0; i++)//此时最多只剩r次替换
sum += tcol[m-i-1];
ans = max(sum, ans);
return;
}
if(r>0) //替换这行
{
for(int i=0; i<m; i++)
col[i] -= x-in[index][i];
dfs(index+1, r-1, sum+row[index]);
for(int i=0; i<m; i++)
col[i] += x-in[index][i];
}
dfs(index+1, r, sum);//不替换这行
}
int main( )
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while(~scanf("%lld%lld%lld%lld", &n,&m,&x,&k))
{
ans = 0;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
scanf("%lld", &in[i][j]);
ans += in[i][j];
}
init( );
dfs(0, k, ans);
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: