[vijos1048]送给圣诞夜的贺卡<DFS剪枝>
题目链接: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剪枝>的更多相关文章
- P1049送给圣诞夜的礼品(矩阵十大问题之四)
https://vijos.org/p/1049 P1049送给圣诞夜的礼品 Accepted 标签:组合数学送给圣诞夜的礼物[显示标签] 返回代码界面 | 关闭 Pascal Pasca ...
- Codevs 1293 送给圣诞夜的极光
1293 送给圣诞夜的极光 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 圣诞老人回到了北极圣 ...
- vijosP1049 送给圣诞夜的礼品
vijosP1049 送给圣诞夜的礼品 链接:https://vijos.org/p/1049 [思路] 快速幂+矩阵转换. 将m次矩阵的转换看作是一次快速幂中的乘法操作,这样可以用O(log(k/m ...
- codevs1293送给圣诞夜的极光(bfs)
1293 送给圣诞夜的极光 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 圣诞老人回到了北极圣诞区,已经快到12点了 ...
- [vijos]1051送给圣诞夜的极光<BFS>
送给圣诞夜的极光 题目链接:https://www.vijos.org/p/1051 这是一道很水很水的宽搜水题,我主要是觉得自己在搜素这一块有点生疏于是随便找了一题练手,找到这么一道水题,原本以为可 ...
- 洛谷 P1454 圣诞夜的极光 == codevs 1293 送给圣诞夜的极光
题目背景 圣诞夜系列~~ 题目描述 圣诞老人回到了北极圣诞区,已经快到12点了.也就是说极光表演要开始了.这里的极光不是极地特有的自然极光景象.而是圣诞老人主持的人造极光. 轰隆隆……烟花响起(来自中 ...
- Vijos1051. 送给圣诞夜的极光
试题请參见: https://vijos.org/p/1051 题目概述 圣诞老人回到了北极圣诞区, 已经快到12点了. 也就是说极光表演要開始了. 这里的极光不是极地特有的自然极光景象. 而是圣诞老 ...
- vijos 1047 送给圣诞夜的礼品 矩阵
题目链接 描述 当小精灵们把贺卡都书写好了之后.礼品准备部的小精灵们已经把所有的礼品都制作好了.可是由于精神消耗的缘故,他们所做的礼品的质量越来越小,也就是说越来越不让圣诞老人很满意.可是这又是没有办 ...
- 【vijos1049】送给圣诞夜的礼品
题面 描述 当小精灵们把贺卡都书写好了之后.礼品准备部的小精灵们已经把所有的礼品都制作好了.可是由于精神消耗的缘故,他们所做的礼品的质量越来越小,也就是说越来越不让圣诞老人很满意.可是这又是没有办法的 ...
随机推荐
- 将list集合按指定长度进行切分,返回新的List<List<??>>集合
Lists.partition public class testList { @Test public void test(){ List<Integer> numList = List ...
- 自定义checkbox, radio样式总结
任务目的 深入了解html label标签 了解CSS边框.背景.伪元素.伪类(注意和伪元素区分)等属性的设置 了解CSS中常见的雪碧图,并能自己制作使用雪碧图 任务描述 参考 样例(点击查看),实现 ...
- OpenCV中Mat的基本用法:创建、复制
OpenCV中Mat的基本用法:创建.复制 一.Mat类的创建: 1.方法一: 通过读入一张图像,直接将其转换成Mat对象. Mat image = imread("test.jpg&quo ...
- MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询
对于一对一,一对多的关联查询,Mybatis-Plus官方示例(mybatis-plus-sample-resultmap)在处理时,需要编写查询方法及配置resultMap,并且写SQL. 为了简化 ...
- 简单配置Vue路由
简单配置Vue路由 1. 创建一个单文件组件Test.vue <template> <div>Test</div> </template> <s ...
- C语言程序设计(九) 指针
第九章 指针 C程序中的变量都是存储在计算机内存特定的存储单元中的,内存中的每个单元都有唯一的地址 通过取地址运算符&可以获得变量的地址 //L9-1 #include <stdio.h ...
- ReentrantReadWriteLock 源码分析以及 AQS 共享锁 (二)
前言 上一篇讲解了 AQS 的独占锁部分(参看:ReentrantLock 源码分析以及 AQS (一)),这一篇将介绍 AQS 的共享锁,以及基于共享锁实现读写锁分离的 ReentrantReadW ...
- npm 安装包总结
1.前端可视化json:vue-json-viewer; 2.富文本编辑: vue-quill-editor; https://www.cnblogs.com/ZaraNet/p/1020922 ...
- 在Java中使用Collections.sort 依据多个字段排序
一.如何使用Collections工具类进行排序 使用Collections工具类进行排序主要有两种方式: 1.对象实现Comparable接口,重写compareTo方法 /** * @author ...
- 《Java8 Stream编码实战》正式推出
当我第一次在项目代码中看到Stream流的时候,心里不由得骂了一句"傻X"炫什么技.当我开始尝试在代码中使用Stream时,不由得感叹真香. 记得以前有朋友聊天说,他在代码中用了 ...