题目链接: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. 丰富图文详解B-树原理,从此面试再也不慌

    本文始发于个人公众号:TechFlow,原创不易,求个关注 本篇原计划在上周五发布,由于太过硬核所以才拖到了这周五.我相信大家应该能从标题当中体会到这个硬核. 周五的专题是大数据和分布式,我最初的打算 ...

  2. 从输入URL到页面展示

    当我们输入 URL 并按回车后,浏览器会对 URL 进行检查,首先判断URL格式,比如是ftp http ed2k等等,我们这里假设这个URL是http://hellocassie.cn,那么浏览器会 ...

  3. 【原创】(四)Linux进程调度-组调度及带宽控制

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  4. 使用vue cli3新建一个vue项目

    写在最前 虽然身为一个java后端工作者,前端还是要沾点的,基于vue的火热,所以平常的工作中项目前端基本都是vue.这次就主要讲一讲vue项目的创建,并从vue的安装开始讲起,附带上我之前安装使用时 ...

  5. golang sms阿里云发送短信(公司实际项目)

    话不多说,直接上代码!!! 要先下载两个包 (可以go get -u +你想要的包) github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests githu ...

  6. MySQL记录操作(增删改)

    概览 MySQL数据操作: DML 在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用DELETE实现数据 ...

  7. Scala尾递归

    递归函数应用 首先,我们来对比两个递归方法的求值步骤. 假设有方法gcd,用来计算两个数的最大公约数.下面是欧几里得算法的实现: def gcp(a: Int, b: Int): Int = if ( ...

  8. 杂谈 | 习得性无助&习得性乐观

    习得性无助和习得性乐观简述 这两个概念均出自积极心理学家Martin Seligman. “习得性无助”的提出是基于一项动物实验. 狗关在笼子里,只要蜂音器一响,就对狗施予电击,狗在笼子里无法躲避电击 ...

  9. CVE-2018-1000861复现

    1. 漏洞描述 Jenkins使用Stapler框架开发,其允许用户通过URL PATH来调用一次public方法.由于这个过程没有做限制,攻击者可以构造一些特殊的PATH来执行一些敏感的Java方法 ...

  10. drf-jwt的过滤,筛选,排序,分页组件

    目录 自定义drf-jwt配置 案例:实现多方式登陆签发token urls.py models.py serializers.py views.py 案例:自定义认证反爬规则的认证类 urls.py ...