您的位置:首页 > 其它

济南学习 Day 2 T3 am

2016-11-07 08:40 274 查看
【问题描述】
m× m的方阵上有n棵葱,你要修一些栅栏把它们围起来。一个栅栏是一段
沿着网格建造的封闭图形(即要围成一圈) 。各个栅栏之间应该不相交、不重叠
且互相不包含。如果你最多修k个栅栏,那么所有栅栏的长度之和最小是多少?
【输入格式】
第一行三个整数m,k,n。
接下来n行每行两个整数x,y代表某棵葱的位置。
【输出格式】
一行一个整数代表答案。
【样例输入 1】
6 1 4
1 3
4 2
4 4
6 4
【样例输出 1】
18
【样例输入 2】
6 2 4
1 3
4 2
4 4
6 4
【样例输出 2】
16
【样例解释】
你猜树上有啥。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e6+10;
const int M=20;
int m,n,k,xx[M],yy[M];
int cost
,s[M];
int tot,nowmask,answer,full;
struct rect{
int x1,x2,y1,y2;
int mask,w;
rect(){}
rect(int _x1,int _y1,int _x2,int _y2){
x1=_x1,y1=_y1,x2=_x2,y2=_y2;
mask=0;
for(int i=0;i<n;i++) if(x1<=xx[i]&&xx[i]<=x2&&y1<=yy[i]&&yy[i]<=y2) mask|=(1<<i);
w=((x2-x1+1)+(y2-y1+1))*2;
if(mask==full) answer=w;
}
}a
;
void dfs(int cnt,int j,int cost){
if(nowmask==full){
//if(clock()>=1950){printf("%d",answer);exit(0);}
answer=min(answer,cost);return ;
}
if(cnt>=k||j>tot||cost>=answer) return ;
for(int i=j;i<=tot;i++){
if(nowmask&a[i].mask) continue;
nowmask^=a[i].mask;
dfs(cnt+1,i+1,cost+a[i].w);
nowmask^=a[i].mask;
}
}
void DFS(int now,int cnt,int res){
if(now==n){
if(res<answer) answer=res;return;
}
if(res+(k-cnt)*4>=answer) return;
for(int i=1;i<=cnt;i++){
int pres=s[i];
s[i]|=(1<<now);
DFS(now+1,cnt,res-cost[pres]+cost[s[i]]);
s[i]^=(1<<now);
}
if(cnt<k){
s[++cnt]=(1<<now);
DFS(now+1,cnt,res+4);
}
}
#define name "dan"
int main(){
scanf("%d%d%d",&m,&k,&n);
full=(1<<n)-1;
for(int i=0;i<n;i++) scanf("%d%d",&xx[i],&yy[i]);
if(n<15){
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
for(int k=j;k<n;k++){
for(int l=k;l<n;l++){
a[++tot]=rect(min(min(xx[i],xx[j]),min(xx[k],xx[l])),min(min(yy[i],yy[j]),min(yy[k],yy[l])),
max(max(xx[i],xx[j]),max(xx[k],xx[l])),max(max(yy[i],yy[j]),max(yy[k],yy[l])));
}
}
}
}
nowmask=0;
dfs(0,1,0);
printf("%d",answer);
}
else{
answer=4000;
for(int i=1;i<=full;i++){
int sx=1001,mx=-1,sy=1001,my=-1;
for(int j=0;j<n;j++){
if((i>>j)&1){
if(xx[j]<sx) sx=xx[j];
if(xx[j]>mx) mx=xx[j];
if(yy[j]<sy) sy=yy[j];
if(yy[j]>my) my=yy[j];
}
}
cost[i]=(mx-sx+1)*2+(my-sy+1)*2;
}
DFS(0,0,0);
printf("%d",answer);
}
return 0;
}


版权申明:转载于shenben

思路:搜索,好好理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: