题目链接:https://www.vijos.org/p/1048

很多人一看就想出了思路,不就是一个裸的dfs蛮。。。但是。。在n<=50的情况下,朴素会直接tle。。。。。

然后我就开始剪枝,剪了很多地方,然后多过了一个点。。。。。然后我就发现我的剪枝和我的dfs打的不行

然后我们先看看朴素的打法(打法多,我是一种非常原始的朴素算法)

 bool check(int x,int dep){
for(int i=;i<=dep;i++)
if(map[a[i]][x]==)return ;
return ;
} void dfs(int dep,int pos){
if(dep==m+){ans=max(ans,s);return;}
if(s+tot[n]-tot[pos-]<=ans)return;
for(int i=;i<=n,dep-+n-i+>=m;i++){
if(vis[i]==&&check(e[i].ord,dep-)){
vis[i]=;
a[dep]=e[i].ord;
s+=val[i];
dfs(dep+,i+);
s-=val[i];
a[dep]=;
vis[i]=;
}
}
return ;
}

然后我的这个dfs本身就不够优化。。我其实可以换成不扩展深度dep,而是扩展当前的指针pos,代替我原来程序的i

另一个优化的地方,在这个朴素的程序里面也有,就是维护一个前缀和,如果当前值的大小+后面未遍历的所有值<=我们当前的ans,就跳过

然后就是对于是不是有矛盾的判断,我的朴素算法是邻接矩阵来暴力跑个O(n)来判断

这个位置可以优化,我们开一个二维数组en[i][j],其中i代表初始序号为i的数,en[i][0]存这个i多少有矛盾的人,然后j就是第几个矛盾的人,e[i][j]就是和i有矛盾的第j个人的序号

然后在判断时加一个enm[x]数组,如果enm[x]==0,说明当前x是没有敌人的,然后就把x 的所有敌人的enm[i]++,标记这些人就有敌人了。。。

然后还剩一个优化的地方,就是排序,这个排序的主要作用是配合我们维护前缀和的剪枝,不过排序要注意排序后的序号和输入矛盾两人的序号可能不同,输入矛盾序号是按照最开始的序号来的,所以要稍微处理一下这个细节

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define maxn 60
using namespace std; int n,m,ans,s,sum,val[maxn],a[maxn],vis[maxn];
int tot[maxn],en[maxn][maxn],enm[maxn];
struct node{
int v,ord;
}e[maxn]; int comp(const void*a,const void*b){
return (*(struct node*)a).v<(*(struct node*)b).v?:-;
} void dfs(int pos){
if(pos==n+){ans=max(ans,s);return;}
if(s+tot[n]-tot[pos-]<=ans)return;
int o=e[pos].ord;
if(enm[o]==){
for(int i=;i<=en[o][];i++)
enm[en[o][i]]++;
s+=e[pos].v;
dfs(pos+);
s-=e[pos].v;
for(int i=;i<=en[o][];i++)
enm[en[o][i]]--;
}
dfs(pos+);
} int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&val[i]);e[i].v=val[i];e[i].ord=i;
}
e[].v=0x3f3f3f;
qsort(e,n+,sizeof(e[]),comp);
for(int i=;i<=n;i++){
tot[i]=tot[i-]+e[i].v;
}
int x,y;
while(scanf("%d%d",&x,&y)!=EOF){
en[x][++en[x][]]=y;
en[y][++en[y][]]=x;
}
dfs();
printf("%d",ans);
}

【总结】

DFS的优化着手点:

1.数据排序,加上对未来最大情况判断(本题表现为前缀和)

2.DFS的参数不用dep(选了几个数),而用pos(正在判断第几个数)

3.记录与自己有关系的人,不用邻接矩阵,用list[i][j]表示,list[i][0]为和自己有关系的人的个数

[vijos1048]送给圣诞夜的贺卡<DFS剪枝>的更多相关文章

  1. P1049送给圣诞夜的礼品(矩阵十大问题之四)

    https://vijos.org/p/1049 P1049送给圣诞夜的礼品 Accepted 标签:组合数学送给圣诞夜的礼物[显示标签]     返回代码界面 | 关闭   Pascal Pasca ...

  2. Codevs 1293 送给圣诞夜的极光

    1293 送给圣诞夜的极光  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 圣诞老人回到了北极圣 ...

  3. vijosP1049 送给圣诞夜的礼品

    vijosP1049 送给圣诞夜的礼品 链接:https://vijos.org/p/1049 [思路] 快速幂+矩阵转换. 将m次矩阵的转换看作是一次快速幂中的乘法操作,这样可以用O(log(k/m ...

  4. codevs1293送给圣诞夜的极光(bfs)

    1293 送给圣诞夜的极光  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 圣诞老人回到了北极圣诞区,已经快到12点了 ...

  5. [vijos]1051送给圣诞夜的极光<BFS>

    送给圣诞夜的极光 题目链接:https://www.vijos.org/p/1051 这是一道很水很水的宽搜水题,我主要是觉得自己在搜素这一块有点生疏于是随便找了一题练手,找到这么一道水题,原本以为可 ...

  6. 洛谷 P1454 圣诞夜的极光 == codevs 1293 送给圣诞夜的极光

    题目背景 圣诞夜系列~~ 题目描述 圣诞老人回到了北极圣诞区,已经快到12点了.也就是说极光表演要开始了.这里的极光不是极地特有的自然极光景象.而是圣诞老人主持的人造极光. 轰隆隆……烟花响起(来自中 ...

  7. Vijos1051. 送给圣诞夜的极光

    试题请參见: https://vijos.org/p/1051 题目概述 圣诞老人回到了北极圣诞区, 已经快到12点了. 也就是说极光表演要開始了. 这里的极光不是极地特有的自然极光景象. 而是圣诞老 ...

  8. vijos 1047 送给圣诞夜的礼品 矩阵

    题目链接 描述 当小精灵们把贺卡都书写好了之后.礼品准备部的小精灵们已经把所有的礼品都制作好了.可是由于精神消耗的缘故,他们所做的礼品的质量越来越小,也就是说越来越不让圣诞老人很满意.可是这又是没有办 ...

  9. 【vijos1049】送给圣诞夜的礼品

    题面 描述 当小精灵们把贺卡都书写好了之后.礼品准备部的小精灵们已经把所有的礼品都制作好了.可是由于精神消耗的缘故,他们所做的礼品的质量越来越小,也就是说越来越不让圣诞老人很满意.可是这又是没有办法的 ...

随机推荐

  1. 开发项目是Integer 与int 什么时候用

    什么时候用Integer : 如果该属性所对应的数据库的字段是主键或者是外键时,用Integer:因为Integer的默认值为null,数据库的主键或者外键不能为空,但是可以为null 什么时候用in ...

  2. Canvas 使用及应用

    Canvas canvas 是 HTML5 当中我最喜欢的所有新特性中我最喜欢的一个标签了.因为它太强大了,各种有意思的特效都可以实现. 1. canvas 的基本使用方法 - 它是一个行内块元素 - ...

  3. Flex布局做出自适应页面--语法和案例

    本文发布在: github项目地址:https://github.com/tenadolanter/flex-layout-demo SegmentFault地址:https://segmentfau ...

  4. 【前端性能优化】高性能JavaScript整理总结

    高性能JavaScript整理总结 关于前端性能优化:首先想到的是雅虎军规34条然后最近看了<高性能JavaScript>大概的把书中提到大部分知识梳理了下并加上部分个人理解这本书有参考雅 ...

  5. Java基础--Arrays类

    Arrays工具类:用来操作数组(比如排序和搜索)的各种方法 常用方法: 使用二分法查找 Arrays.binarySearch(int[]array,int value); 数组内容转换成字符串的形 ...

  6. Django进行数据迁移时,报错:(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")

    进行数据迁移时: 第一步: 命令:python manage.py makemigrations 在对应的应用里面的migrations文件夹中产生了一个0001_initial.py文件 第二步:执 ...

  7. springcloud gateway整合sentinel

    1.引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spri ...

  8. 第二章、 Vue 起步

    2-2.编写hello world 首先创建vue实例,然后实例接收一些配置项,el表示实例负责管理的区域,data表示区域内的数据 两秒后内容变为bye world 其中app表示实例对象,$dat ...

  9. 有关vue中用element ui 中的from表单提交json格式总是有冒号的问题解决办法

    因为后台要求要传递JSON格式的数据给他,然后我转了之后总是多了冒号,后来又看了自己的报错,原来是报了404错误,说明路径找不到, 数据格式 后来发现怎么都不行了,然后突然查看了报错报的是404,说明 ...

  10. plist 图集 php 批量提取 PS 一个个切

    最近,迷上了用 cocos2d 做游戏开发.由于是新入门,很多东西从头开始学. 在使用 sprite 的 Rect 裁剪显示的时候,显示总是多一块.所以,要从图集中提取一张张图,这样就省了裁剪. 原图 ...