题意:
有一个n*m的矩阵,你可以进行k回合的游戏,每一回合将矩阵的一行或者一列的值置零并将分数加上。求你最后最多能得多少分?
思路:
由于消除行对列有影响,所以不能简单的贪心,但你n和m小于15,所以我可以枚举消除列的状态,然后对每一种合理状态再对行进行贪心操作,然后取最大分数值。
代码:
#include<bits/stdc++.h> #define ll long long #define inf 1000000007 using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } int d[20][20], n, m, rl[20], cl[20], r[20], ki; bool cmp(int a,int b) { return a>b; } int main() { scanf("%d%d%d",&n,&m,&ki); for(int i=0; i<n; i++) { rl[i]=0; for(int j=0; j<m; j++) { scanf("%d",&d[i][j]); rl[i]+=d[i][j]; } } for(int j=0; j<m; j++) { cl[j]=0; for(int i=0; i<n; i++) { cl[j]+=d[i][j]; } } int k=0; int pa=(1<<m); int ans=0; for(;k<pa;k++) { int sum=0, pan=ki; memset(r,0,sizeof(r)); for(int j=0; j<m; j++) { if((k>>j)&1) { pan--; sum=sum+cl[j]; } else { for(int i=0; i<n; i++) { r[i]+=d[i][j]; } } } if(pan<0) { continue; } sort(r,r+n,cmp); for(int i=0;i<pan&&i<n;i++) { sum=sum+r[i]; } ans=max(sum,ans); } cout << ans << endl; return 0; }