点击打开链接
3 3 3 1 1 3 1 2 1 1 1 2 5 4 3 2 2 3 3 1 1 3 3 3 2 2 2 3 1 1 1 3 1 2 2
36 103
题解:由于图很小,直接暴搜,然后加上最优性剪枝即可。
最优性剪枝:如果当前图的所有宝石都能消,判断会不会使答案最优,不会则减掉。
代码如下:
#include<stdio.h> #include<algorithm> #include<iostream> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<string.h> #include<string> #include<math.h> #define nn 2100 #define eps 1e-8 #define inff 0x3fffffff typedef long long LL; using namespace std; int dir[8][2]={1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1}; int n,m,k; int ys[7]; int ans; struct node { int x,y; node(){}; node(int xx,int yy) { x=xx,y=yy; } }sta; struct sz { int a[8][8]; }tu; node que[110]; sz zhuan(sz x) { int i,j; int ix; sz re; memset(re.a,0,sizeof(re.a)); for(i=0;i<m;i++) { ix=n-1; for(j=n-1;j>=0;j--) { if(x.a[j][i]!=0) { re.a[ix][i]=x.a[j][i]; ix--; } } } memset(x.a,0,sizeof(x.a)); ix=0; for(i=0;i<m;i++) { if(re.a[n-1][i]!=0) { for(j=0;j<n;j++) { x.a[j][ix]=re.a[j][i]; } ix++; } } return x; } bool check(int x,int y) { if(x<0||x>=n||y<0||y>=m) return false; return true; } void dfs(sz s,int val) { if(val>ans) ans=val; int i,j,g,e; bool use[8][8]; sz tem; memset(ys,0,sizeof(ys)); for(i=0;i<n;i++) { for(j=0;j<m;j++) { use[i][j]=false; if(s.a[i][j]!=0) { ys[s.a[i][j]]++; } } } int ix=0; for(i=1;i<=k;i++) { ix+=ys[i]*ys[i]; } if(ix+val<=ans) return ; node ve[65]; int dx,dy; int top,pop,lv; for(g=0;g<n;g++) { for(e=0;e<m;e++) { tem.a[g][e]=s.a[g][e]; } } for(i=0;i<n;i++) { for(j=0;j<m;j++) { if(!use[i][j]&&s.a[i][j]) { lv=0; top=pop=0; use[i][j]=true; tem.a[i][j]=0; ve[lv++]=node(i,j); que[pop++]=node(i,j); while(top!=pop) { sta=que[top++]; for(g=0;g<8;g++) { dx=sta.x+dir[g][0],dy=sta.y+dir[g][1]; if(check(dx,dy)&&!use[dx][dy]&&s.a[dx][dy]==s.a[i][j]) { tem.a[dx][dy]=0; use[dx][dy]=true; ve[lv++]=node(dx,dy); que[pop++]=node(dx,dy); } } } if(lv>=3) { dfs(zhuan(tem),val+lv*lv); } for(g=0;g<lv;g++) { tem.a[ve[g].x][ve[g].y]=s.a[i][j]; } } } } } int main() { int i,j; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%d",&tu.a[i][j]); } } ans=0; dfs(tu,0); printf("%d\n",ans); } return 0; }
第二次做这题的代码:
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<string> #include<stack> #include<math.h> #include<string.h> #include<vector> #include<set> #include<map> #include<queue> #define nn 110000 #define inff 0x7fffffff #define eps 1e-8 #define mod 1500007 typedef __int64 LL; const LL inf64=LL(inff)*inff; using namespace std; int n,m,K; int ans; int num[7]; queue<pair<int,int> >que; int dir[8][2]={1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1}; void dfs(int tu[8][8],int val) { int i,j,k,e; int ix=0; for(i=1;i<=K;i++) { ix+=num[i]*num[i]; } ans=max(ans,val); if(ix==0||ix+val<=ans) return ; bool use[8][8]; int tem[8][8]; pair<int,int>sta; int dx,dy; int fc; memset(use,false,sizeof(use)); for(i=0;i<n;i++) { for(j=0;j<m;j++) { if(tu[i][j]!=0&&!use[i][j]) { for(k=0;k<n;k++) { for(e=0;e<m;e++) { tem[k][e]=tu[k][e]; } } use[i][j]=true; que.push(make_pair(i,j)); tem[i][j]=0; ix=0; while(que.size()) { sta=que.front(); ix++; que.pop(); for(k=0;k<8;k++) { dx=sta.first+dir[k][0]; dy=sta.second+dir[k][1]; if(dx>=0&&dx<n&&dy>=0&&dy<m) { if(!use[dx][dy]&&tem[dx][dy]==tu[i][j]) { use[dx][dy]=true; tem[dx][dy]=0; que.push(make_pair(dx,dy)); } } } } if(ix<3) continue; for(e=0;e<m;e++) { fc=n-1; for(k=n-1;k>=0;k--) { if(tem[k][e]!=0) { if(fc==k) fc--; else { tem[fc--][e]=tem[k][e]; tem[k][e]=0; } } } } fc=0; for(e=0;e<m;e++) { for(k=n-1;k>=0;k--) { if(tem[k][e]!=0) { break; } } if(k>=0) { if(e==fc) fc++; else { for(k=n-1;k>=0;k--) { tem[k][fc]=tem[k][e]; tem[k][e]=0; } fc++; } } } num[tu[i][j]]-=ix; dfs(tem,val+ix*ix); num[tu[i][j]]+=ix; } } } } int main() { int i,j; int s[8][8]; while(scanf("%d%d%d",&n,&m,&K)!=EOF) { memset(num,0,sizeof(num)); for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%d",&s[i][j]); num[s[i][j]]++; } } ans=0; dfs(s,0); printf("%d\n",ans); } return 0; }