例题:
题目描述
牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是n行m列,第i行第j列的单元格的权值为a[i][j],牛妹可以进行k个回合的游戏,在每个回合,牛妹可以选择一行或者选择一列,然后将这一行或者这一列的所有单元格中的权值变为0,同时牛妹的分数会加上这一行或者这一列中的所有单元格的权值的和。
牛妹想最大化她的得分,球球你帮帮她吧!
输入描述:
第一行三个整数n,m,k 接下来n行每行m个整数表示矩阵中各个单元格的权值。
输出描述:
输出一个整数表示牛妹能获得的最大分数。
如果只能选择行或者列的话,只要从大到小选择即可,因此我们只要枚举出行或者列的所有情况,再对另一个方向的进行贪心选择即能得出最大的分数。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[16][16];
int aa[16];
int bb[16];
int cc[16];
bool cmp(int x,int y)
{
return x > y;
}
int main()
{
int n,m,k;cin >> n >> m >> k;
int tsum = 0;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
{
cin >> a[i][j];
tsum += a[i][j];
aa[i] += a[i][j];
bb[j] += a[i][j];
}
if(k >= min(n,m))
cout << tsum;
else//枚举后贪心
{
int ma = 0;
for(int i = 0;i < (1 << n);i++)
{
int nn = 0;
for(int t = 1;t <= m;t++)
cc[t] = bb[t];
int sum = 0;
int ii = i;
int l = 0;
while(ii)
{
if(ii & (1 << l++))
{
for(int t = 1;t <= m;t++)
cc[t] -= a[l][t];
nn++;
sum += aa[l];
ii -= (1 << (l - 1));
}
}
if(k - nn >= 0)
{
sort(cc + 1,cc + 1 + m,cmp);
for(int t = 1;t <= k - nn;t++)
sum += cc[t];
ma = max(sum,ma);
}
}
cout << ma;
}
}