AcWing168 生日蛋糕 dfs 剪枝

2024-01-28 15:48

本文主要是介绍AcWing168 生日蛋糕 dfs 剪枝,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AcWing 168 生日蛋糕 dfs 剪枝

原题链接(https://www.acwing.com/problem/content/description/170/)

思路:

要求最小的表面积,可知上表面总面积等于最底层蛋糕的上表面面积,那么就只需要求侧面积的最小值。预处理s的最小值时,将蛋糕从上往下,h,r都为1开始,往下面依次递增。
由于每一层与dep,s,v,r,h,R[dep+1],H[dep+1]有关,那么每一层都是一个状态,所以采用dfs。
搜索到dep层时,本层蛋糕的s与v由r和h求得。因为从下往上,r的下界为dep,因为这是预处理时满足最小值的s。上界:由蛋糕满足高度和半径单调递减,那么r<=R[dep+1]-1,另一方面,那么又因为每一层蛋糕的体积满足PIRRH=PI(N-V),
当H=1时,R最大为sqrt(N-V).
所以r的范围为[dep,min(sqrt(N-V),R[dep+1]-1)]
同理的h的范围为[dep,min((N-V)/r*r,H[dep+1]-1)]

剪枝:
1,s: 当前s加上预处理的本层最小的s之后大于了ans,return
2.v:当前v加上预处理的本层最小的v之后大于了N,return
3.S = sum(2RiHi),V = sum(RiRiHi),则S = sum(2RiHiRk+1 / Rk+1) > 1 / Rk+1 * sum(2RiRiHi ) = 2 / Rk+1 * sum(RiRiHi) = 2V / Rk+1,所以当2*(N-V)/R[dep] + s > ans时,continue;

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int H[25],R[25],mins[25],minv[25],n,m,ans=INF;
void dfs(int dep,int v, int s){//dfs变量:dep,s,v 剪枝:s,v,s与v的关系,dep  //剪枝 if(s+mins[dep]>ans) return;//面积:已经不是最优的 if(v+minv[dep]>n) return;//体积 :已经超过了规定的体积 if(2*(n-v)/R[dep+1]+s>ans) return;//面积与体积的关系推出的奇奇怪怪的剪枝策略 if(dep==0){//递归边界 if(v==n) ans=min(ans,s);//如果同时还满足v==n,那么更新ans return;} for(int r=min((int)sqrt(n-v),R[dep+1]-1);r>=dep;r--){//下界:dep,上界:min(首先满足从下往上单调递减,所以满足R[dep+1]-1,又根据公式PI*r*r*h=PI*(N-v) for(int h=min((n-v)/(r*r),H[dep+1]-1);h>=dep;h--){int t=0;if(dep==m) t=r*r;//最下面那层,也是开始搜索的第一层,加上整体的上表面的面积 R[dep]=r,H[dep]=h;//更新r和dep dfs(dep-1,v+r*r*h,s+2*r*h+t);//往下一层搜素 }}
}
int main(){for(int i=1;i<=20;i++){//预处理出最小的,当从上往下r,h,同时为1,2,3这样递增时,显然满足smin mins[i]=mins[i-1]+2*i*i;//s=2*PI*r*h,此时默认r,h相同且从1开始递增 minv[i]=minv[i-1]+i*i*i;}scanf("%d%d",&n,&m);H[m+1]=R[m+1]=INF;//设置边界 dfs(m,0,0);//从最下面一层开始dfs if(ans==INF) puts("0");else printf("%d\n",ans);return 0;
}

这篇关于AcWing168 生日蛋糕 dfs 剪枝的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/654088

相关文章

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

hdu1010 奇偶剪枝

恰好t时间到达 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.Arrays;import

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

HTML生日蛋糕

目录 写在前面 完整代码 代码分析 系列文章 写在最后 写在前面 HTML实现的生日蛋糕来喽,小编亲测,发给好友可以直接打开哦。在代码的第183行可以写下对朋友的祝福,快拿去送给你的好朋友吧! 完整代码 <!DOCTYPE html><html lang="en" ><head><meta charset="UTF-8"><title>Happy Birthd

nyoj99(并查集+欧拉路+dfs)

单词拼接 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串。 前一个单词的结尾应该与下一个单词的道字母相同。 如 aloha dog arachnid gopher tiger rat   可以拼接成:aloha.arachnid.dog.gopher.rat.tiger 输入 第一行是一个整