赌上一切的95分!
源代码: #include<cstdio> #include<ctime> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int m,n,k,Ans=1000000000,X[25],Y[25],i[25],Lx[25],Ly[25],Rx[25],Ry[25]; //这些都是上左下右角标。 void DFS(int t) //暴力搜索,t表示葱数。 { if (clock()>=1950) //丧心病狂!不过我喜欢- -。 { printf("%d",Ans); exit(0); } if (t>n) //围好了。 { int Sum(0); for (int a=1;a<=k;a++) if (i[a]) //修了此栅栏。 Sum+=(Rx[a]-Lx[a]+Ry[a]-Ly[a]+2)<<1; Ans=min(Ans,Sum); return; } int Sum(0); for (int a=1;a<=k;a++) if (i[a]) Sum+=(Rx[a]-Lx[a]+Ry[a]-Ly[a]+2)<<1; if (Sum>=Ans) //剪枝。 return; for (int a=1;a<=k;a++) //仔细想一想这种搜索方法,发现可以像多维循环一样,涵盖所有情况。 { int t1=Lx[a],t2=Ly[a]; int T1=Rx[a],T2=Ry[a]; Lx[a]=min(Lx[a],X[t]),Ly[a]=min(Ly[a],Y[t]); Rx[a]=max(Rx[a],X[t]),Ry[a]=max(Ry[a],Y[t]); i[a]++; DFS(t+1); Lx[a]=t1,Ly[a]=t2; Rx[a]=T1,Ry[a]=T2; i[a]--; } } int main() { memset(Lx,0x3f,sizeof(Lx)); memset(Ly,0x3f,sizeof(Ly)); //初始化。 scanf("%d%d%d",&m,&k,&n); for (int a=1;a<=n;a++) scanf("%d%d",&X[a],&Y[a]); DFS(1); printf("%d",Ans); return 0; }