济南学习 Day 2 T3 am

【问题描述】
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
【样例解释】
你猜树上有啥。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=1e6+10;
 5 const int M=20;
 6 int m,n,k,xx[M],yy[M];
 7 int cost[N],s[M];
 8 int tot,nowmask,answer,full;
 9 struct rect{
10     int x1,x2,y1,y2;
11     int mask,w;
12     rect(){}
13     rect(int _x1,int _y1,int _x2,int _y2){
14         x1=_x1,y1=_y1,x2=_x2,y2=_y2;
15         mask=0;
16         for(int i=0;i<n;i++) if(x1<=xx[i]&&xx[i]<=x2&&y1<=yy[i]&&yy[i]<=y2) mask|=(1<<i);
17         w=((x2-x1+1)+(y2-y1+1))*2;
18         if(mask==full) answer=w;
19     }
20 }a[N];
21 void dfs(int cnt,int j,int cost){
22     if(nowmask==full){
23         //if(clock()>=1950){printf("%d",answer);exit(0);}
24         answer=min(answer,cost);return ;
25     }
26     if(cnt>=k||j>tot||cost>=answer) return ;
27     for(int i=j;i<=tot;i++){
28         if(nowmask&a[i].mask) continue;
29         nowmask^=a[i].mask;
30         dfs(cnt+1,i+1,cost+a[i].w);
31         nowmask^=a[i].mask;
32     }
33 }
34 void DFS(int now,int cnt,int res){
35     if(now==n){
36         if(res<answer) answer=res;return;
37     }
38     if(res+(k-cnt)*4>=answer) return;
39     for(int i=1;i<=cnt;i++){
40         int pres=s[i];
41         s[i]|=(1<<now);
42         DFS(now+1,cnt,res-cost[pres]+cost[s[i]]);
43         s[i]^=(1<<now);
44     }
45     if(cnt<k){
46         s[++cnt]=(1<<now);
47         DFS(now+1,cnt,res+4);
48     }
49 }
50 #define name "dan"
51 int main(){
52     scanf("%d%d%d",&m,&k,&n);
53     full=(1<<n)-1;
54     for(int i=0;i<n;i++) scanf("%d%d",&xx[i],&yy[i]);
55     if(n<15){
56         for(int i=0;i<n;i++){
57             for(int j=i;j<n;j++){
58                 for(int k=j;k<n;k++){
59                     for(int l=k;l<n;l++){
60                         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])),
61                                 max(max(xx[i],xx[j]),max(xx[k],xx[l])),max(max(yy[i],yy[j]),max(yy[k],yy[l])));
62                     }
63                 }
64             }
65         }
66         nowmask=0;
67         dfs(0,1,0);
68         printf("%d",answer);
69     }
70     else{
71         answer=4000;
72         for(int i=1;i<=full;i++){
73             int sx=1001,mx=-1,sy=1001,my=-1;
74             for(int j=0;j<n;j++){
75                 if((i>>j)&1){
76                     if(xx[j]<sx) sx=xx[j];
77                     if(xx[j]>mx) mx=xx[j];
78                     if(yy[j]<sy) sy=yy[j];
79                     if(yy[j]>my) my=yy[j];
80                 }
81             }
82             cost[i]=(mx-sx+1)*2+(my-sy+1)*2;
83         }
84         DFS(0,0,0);
85         printf("%d",answer);
86     }
87     return 0;
88 }

版权申明:转载于shenben

思路:搜索,好好理解

时间: 2024-10-30 16:18:56

济南学习 Day 2 T3 am的相关文章

济南学习 Day 5 T3 am

[题目描述] 众所不知,rly现在不会玩国际象棋.但是,作为一个OIer,rly当然做过八皇后问题.在这里再啰嗦几句,皇后可以攻击到同行同列同对角线,在 n*n的棋盘中,摆放n个皇后使它们互相不能攻击到,求不同的解的数量,这就是经典的n皇后问题.现在问题推广n皇后问题,这个问题对你而言实 在是小菜一碟.但是因为上次rly把棋盘弄破了,又拿不出新的,所以rly打算难一点点,问题就是在破的棋盘上的n皇后问题.他想知道......(你们懂的..) 妻子都是相同的 [输入说明] 一行,一个整数N. 接下

济南学习 Day1 T3 pm

[问题描述]小 Q 对计算几何有着浓厚的兴趣.他经常对着平面直角坐标系发呆,思考一些有趣的问题.今天,他想到了一个十分有意思的题目:首先,小 Q 会在x轴正半轴和y轴正半轴分别挑选??个点.随后,他将x轴的点与y轴的点一一连接,形成??条线段,并保证任意两条线段不相交.小 Q 确定这种连接方式有且仅有一种.最后,小 Q 会给出m个询问.对于每个询问,将会给定一个点P(Px ,Py),请回答线段 OP 与m条线段会产生多少个交点?小 Q 找到了正在钻研数据结构的你,希望你可以帮他解决这道难题.[输

2016.10.30 济南学习 Day2 下午 T1

他 [问题描述] 一张长度为??的纸带,我们可以从左至右编号为0 ? ??(纸带最左端标号为 0).现在有??次操作,每次将纸带沿着某个位置进行折叠,问所有操作之后纸带 的长度是多少. [输入格式] 第一行两个数字??, ??如题意所述. 接下来一行??个整数代表每次折叠的位置. [输出格式] 一行一个整数代表答案. [样例输入] 5 2 3 5 [样例输出] 2 [样例解释] 树上有只鸟. [数据规模与约定] 对于60%的数据,??, ?? ≤ 3000. 对于100%的数据,?? ≤ 101

济南学习 Day2 T2 am

[问题描述]有??个数,随机选择一段区间,如果这段区间的所有数的平均值在[l,r]中则你比较厉害.求你比较厉害的概率.[输入格式]第一行有三个数N,l,r,含义如上描述.接下来一行有??个数代表每一个数的值.[输出格式]输出一行一个分数 a/b代表答案,其中a,b互质.如果答案为整数则直接输出该整数即可.[样例输入 1]4 2 33 1 2 4[样例输出 1]7/10[样例输入 2]4 1 43 1 2 4[样例输出 2]1[样例解释]塔外面有棵树.[数据规模与约定]对于30%的数据,1<=N<

济南学习D2T1__折纸带

他[问题描述]一张长度为n的纸带,我们可以从左至右编号为0 ?n(纸带最左端标号为0) .现在有m次操作,每次将纸带沿着某个位置进行折叠,问所有操作之后纸带的长度是多少.[输入格式]第一行两个数字n,m如题意所述.接下来一行m个整数代表每次折叠的位置.[输出格式]一行一个整数代表答案.[样例输入]5 23 5[样例输出]2[样例解释]树上有只鸟.[数据规模与约定]60%的数据,n,m ≤ 3000.对于100%的数据,n≤ 10 18 ,m ≤ 3000. ___________________

济南学习 Day1 T2 pm

[问题描述]栈是一种强大的数据结构,它的一种特殊功能是对数组进行排序.例如,借助一个栈,依次将数组 1,3,2 按顺序入栈或出栈,可对其从大到小排序:1 入栈:3 入栈:3 出栈:2 入栈:2 出栈:1 出栈.在上面这个例子中,出栈序列是 3,2,1,因此实现了对数组的排序.遗憾的是,有些时候,仅仅借助一个栈,不能实现对数组的完全排序.例如给定数组 2,1,3,借助一个栈,能获得的字典序最大的出栈序列是 3,1,2:2 入栈:1 入栈:3 入栈:3 出栈:1 出栈:2 出栈.请你借助一个栈,对一

济南学习D2T2__数学分析题

[问题描述]有N个数,随机选择一段区间,如果这段区间的所有数的平均值在[l,r]中则你比较厉害.求你比较厉害的概率.[输入格式]第一行有三个数N,l,r,含义如上描述.接下来一行有N个数代表每一个数的值.[输出格式]输出一行一个分数a/b 代表答案,其中a,b互质.如果答案为整数则直接输出该整数即可.[样例输入 1]4 2 33 1 2 4[样例输出 1]7/10[样例输入 2]4 1 43 1 2 4[样例输出 2]1[样例解释]塔外面有棵树.[数据规模与约定]30%的数据,1<=N<=10

济南学习 Day1 T1 am

题意:给你两个日期,问这两个日期差了多少毫秒 1 #include<cstdio> 2 #include<cstring> 3 #include<ctime> 4 #include<iostream> 5 #define ll long long 6 using namespace std; 7 int mth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 8 ll solve(){ 9 int Y=0,M=0,D

济南学习

死亡[问题描述]现在有M个位置可以打 sif,有N +1个人在排队等着打 sif.现在告诉你 个人每个人需要多长的时间打 sif,问你第N +1个人什么时候才能打 sif. (前N个人必须按照顺序来)[输入格式]第一行两个整数N,M如上所述.接下来N行每行一个整数代表每个人所需要用的时间.[输出格式]一行一个整数表示答案.[样例输入]3 2111[样例输出]1[样例解释]山里有座庙.[数据规模与约定]对于100%的数据,每个人所需用的时间不超过10 5 . 1 #include <cstdio>