勇敢的妞妞 ( 狀壓 + 思維)
阿新 • • 發佈:2018-12-16
題目連結:https://ac.nowcoder.com/acm/contest/315/E
具體思路:首先,對於當m>=5的時候,我們可以直接選取每一列中最大的那一個,直接相加就可以.
然後對於當m<5的時候,我們可以採取狀壓的思路,因為列數只有5,所以最多隻有32中情況,所以將每種情況的最優的那一個選取出來,然後再用搜索的方式將最優解再找出來.
AC程式碼:
#include<bits/stdc++.h> using namespace std; # define ll long long const int maxn = 10000+100; # define inf 0x3f3f3f3f const int mod = 1e9; int a[maxn][10]; int viss[maxn]; vector<int>q; int n,m; int ans=0; void dfs(int dt,int tmp[],int num) { if(num==m) { int t=0; for(int i=0; i<5; i++) { t+=tmp[i]; } ans=max(ans,t); return ; } int len=q.size(); for(int i=dt; i<len; i++) { int tmps[10]; memset(tmps,0,sizeof(tmps)); for(int j=0; j<5; j++) { tmps[j]=max(tmp[j],a[q[i]][j]); } dfs(i,tmps,num+1); } } int main() { scanf("%d %d",&n,&m); for(int i=1; i<=n; i++) { for(int j=0; j<5; j++) { scanf("%d",&a[i][j]); } } if(m>=5) { int sum=0; for(int i=0; i<5; i++) { int maxx=0; for(int j=1; j<=n; j++) { maxx=max(maxx,a[j][i]); } sum+=maxx; } printf("%d\n",sum); return 0; } else { int maxstate=(1<<5)-1; for(int i=1; i<=maxstate; i++) { int vis[10]; memset(vis,0,sizeof(vis)); for(int j=0; j<5; j++) { if(((1<<j)&i)!=0) { vis[j]=1; } } int maxx=0,id; for(int j=1; j<=n; j++) { int sum=0; for(int k=0; k<5; k++) { if(vis[k]) { sum+=a[j][k]; } } if(sum>maxx) { maxx=sum; id=j; } } if(viss[id])continue; q.push_back(id); } int ww[10]; memset(ww,0,sizeof(ww)); dfs(0,ww,0); printf("%d\n",ans); } return 0; }