题目链接:https://ac.nowcoder.com/acm/contest/4090/C
题意:牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是n行m列,第i行第j列的单元格的权值为ai,j,牛妹可以进行k个回合的游戏,在每个回合,牛妹可以选择一行或者选择一列,
然后将这一行或者这一列的所有单元格中的权值变为0,同时牛妹的分数会加上这一行或者这一列中的所有单元格的权值的和。牛妹想最大化她的得分,球球你帮帮她吧!
思路:因为每次可以选择行或列,所以不好直接贪心,由于n和m都比较小,所以我们可以先枚举选哪些行,然后选列的时候就可以用贪心了。哎,比赛时怎么都没想到去枚举。
#include<cstdio> #include<cstring> #include<cmath> #include<string> #include<iostream> #include<algorithm> #include<map> #include<vector> #include<queue> using namespace std; typedef long long ll; int a[20][20],b[20][20],c[20]; int n,m,k; bool cmp(int x,int y) { return x>y; } void inif() { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) b[i][j]=a[i][j]; } int fun(int x) { int ans=0; int v=0,u=0; while(x) { v++; if(x%2) { u++; for(int i=1;i<=m;i++) { ans+=b[v][i]; b[v][i]=0; } } x/=2; } if(u>k) return 0; memset(c,0,sizeof(c)); u=min(k-u,m); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) c[i]+=b[j][i]; sort(c+1,c+m+1,cmp); for(int i=1;i<=u;i++) ans+=c[i]; return ans; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); int x=1; for(int i=1;i<=n;i++) x*=2; x--; int ans=0; for(int i=0;i<=x;i++) { inif(); ans=max(ans,fun(i)); } printf("%d ",ans); }