当前位置: 首页 > wzjs >正文

国内做外单的网站有哪些网络推广费用预算表

国内做外单的网站有哪些,网络推广费用预算表,中国建设银行英文网站,wordpress登录查看插件植树 题目描述 小明和朋友们一起去郊外植树,他们带了一些在自己实验室精心研究出的小树苗。 小明和朋友们一共有 nn 个人,他们经过精心挑选,在一块空地上每个人挑选了一个适合植树的位置,总共 nn 个。他们准备把自己带的树苗都…

植树

题目描述

小明和朋友们一起去郊外植树,他们带了一些在自己实验室精心研究出的小树苗。

小明和朋友们一共有 nn 个人,他们经过精心挑选,在一块空地上每个人挑选了一个适合植树的位置,总共 nn 个。他们准备把自己带的树苗都植下去。

然而,他们遇到了一个困难:有的树苗比较大,而有的位置挨太近,导致两棵树植下去后会撞在一起。

他们将树看成一个圆,圆心在他们找的位置上。如果两棵树对应的圆相交,这两棵树就不适合同时植下(相切不受影响),称为两棵树冲突。

小明和朋友们决定先合计合计,只将其中的一部分树植下去,保证没有互相冲突的树。他们同时希望这些树所能覆盖的面积和(圆面积和)最大。

输入描述

输入的第一行包含一个整数 nn ,表示人数,即准备植树的位置数。

接下来 nn 行,每行三个整数 x, y, rx, y, r,表示一棵树在空地上的横、纵坐标和半径。

其中,1≤n≤30,0≤x,y≤1000,1≤r≤10001≤n≤30,0≤x,y≤1000,1≤r≤1000。

输出描述

输出一行包含一个整数,表示在不冲突下可以植树的面积和。由于每棵树的面积都是圆周率的整数倍,请输出答案除以圆周率后的值(应当是一个整数)。

输入输出样例

示例

输入

6
1 1 2
1 4 2
1 7 2
4 1 2
4 4 2
4 7 2

输出

12

运行限制

  • 最大运行时间:3s
  • 最大运行内存: 512M

总通过次数: 524  |  总提交次数: 785  |  通过率: 66.8%

难度: 困难   标签: 2020, 省模拟赛, 搜索

算法思路

本问题需要选择一组互不冲突的树(圆不相交),最大化总覆盖面积(半径平方和)。由于树的数量 n ≤ 30,可以采用深度优先搜索(DFS)配合优化策略:

  1. ​冲突检测​​:两棵树冲突的条件是圆心距² < (r₁ + r₂)²(严格小于,相切不算冲突)
  2. ​连通分量分解​​:将树按冲突关系划分为多个独立子集(分量内树可能冲突,分量间树绝对不冲突)
  3. ​DFS搜索​​:对每个连通分量独立搜索最优解
  4. ​剪枝优化​​:
    • 按半径降序排序(优先选择大半径树)
    • 后缀和剪枝(当前和 + 剩余树最大可能和 ≤ 当前最大值时剪枝)
  5. ​状态压缩​​:对小型分量(≤15 节点)使用位运算 DP 加速

算法步骤

  1. ​输入处理​​:读取树的数量和每棵树的坐标半径
  2. ​按半径降序排序​​:确保优先处理大半径树
  3. ​构建冲突图​​:
    • 计算任意两棵树圆心距²
    • 若圆心距² < (rᵢ + rⱼ)² 则标记冲突
  4. ​分解连通分量​​:
    • 用 BFS/DFS 将树划分为冲突连通的子集
    • 不同分量独立处理
  5. ​分量求解​​:
    • ​小型分量(≤15)​​:状态压缩 DP
    • ​大型分量​​:DFS + 后缀和剪枝
  6. ​结果合并​​:累加各分量最优解

算法演示

代码实现

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#include <unordered_map>
using namespace std;struct Tree {int x, y, r, id;
};// 计算圆心距平方(避免浮点误差)
long long distSq(const Tree& a, const Tree& b) {long long dx = a.x - b.x;long long dy = a.y - b.y;return dx*dx + dy*dy;
}// 冲突检测:圆心距² < (r1+r2)²
bool isConflict(const Tree& a, const Tree& b) {long long rSum = (long long)a.r + b.r;return distSq(a, b) < rSum * rSum;
}// 连通分量分解
vector<vector<int>> findComponents(vector<vector<bool>>& conflict) {int n = conflict.size();vector<bool> visited(n, false);vector<vector<int>> components;for (int i = 0; i < n; ++i) {if (visited[i]) continue;queue<int> q;vector<int> comp;q.push(i);visited[i] = true;while (!q.empty()) {int u = q.front();q.pop();comp.push_back(u);for (int v = 0; v < n; ++v) {if (conflict[u][v] && !visited[v]) {visited[v] = true;q.push(v);}}}components.push_back(comp);}return components;
}// 状态压缩DP(处理小规模分量)
int dpComp(const vector<Tree>& trees, const vector<vector<bool>>& compConflict) {int n = trees.size();if (n == 0) return 0;vector<int> dp(1 << n, 0);int best = 0;for (int mask = 1; mask < (1 << n); ++mask) {bool valid = true;int sumSq = 0;for (int i = 0; i < n && valid; ++i) {if (!(mask & (1 << i))) continue;sumSq += trees[i].r * trees[i].r;for (int j = i + 1; j < n; ++j) {if ((mask & (1 << j)) && compConflict[i][j]) {valid = false;break;}}}if (valid) {dp[mask] = sumSq;best = max(best, sumSq);} else {// 状态转移:枚举子集优化dp[mask] = 0;for (int submask = mask; submask; submask = (submask - 1) & mask) {dp[mask] = max(dp[mask], dp[submask]);}}}return best;
}// DFS + 剪枝(处理大规模分量)
void dfsComp(const vector<Tree>& trees, const vector<vector<bool>>& compConflict,vector<bool>& selected, int index, int currentSum, int& bestSum, const vector<int>& suffix) {if (index == trees.size()) {bestSum = max(bestSum, currentSum);return;}// 剪枝:当前和 + 剩余最大可能和 ≤ 最优解if (currentSum + suffix[index] <= bestSum) return;// 不选当前树dfsComp(trees, compConflict, selected, index + 1, currentSum, bestSum, suffix);// 检查与已选树是否冲突bool noConflict = true;for (int i = 0; i < index; ++i) {if (selected[i] && compConflict[index][i]) {noConflict = false;break;}}// 选当前树(无冲突时)if (noConflict) {selected[index] = true;int newSum = currentSum + trees[index].r * trees[index].r;dfsComp(trees, compConflict, selected, index + 1, newSum, bestSum, suffix);selected[index] = false;}
}int main() {int n;cin >> n;vector<Tree> trees(n);for (int i = 0; i < n; ++i) {cin >> trees[i].x >> trees[i].y >> trees[i].r;trees[i].id = i;}// 按半径降序排序(优化剪枝)sort(trees.begin(), trees.end(), [](const Tree& a, const Tree& b) {return a.r > b.r;});// 构建冲突矩阵vector<vector<bool>> conflict(n, vector<bool>(n, false));for (int i = 0; i < n; ++i) {for (int j = i + 1; j < n; ++j) {conflict[i][j] = conflict[j][i] = isConflict(trees[i], trees[j]);}}// 分解连通分量auto components = findComponents(conflict);int totalSum = 0;for (const auto& comp : components) {if (comp.empty()) continue;// 提取当前分量的树vector<Tree> compTrees;for (int idx : comp) {compTrees.push_back(trees[idx]);}int compSize = compTrees.size();// 构建分量冲突矩阵vector<vector<bool>> compConflict(compSize, vector<bool>(compSize, false));for (int i = 0; i < compSize; ++i) {for (int j = i + 1; j < compSize; ++j) {compConflict[i][j] = compConflict[j][i] = isConflict(compTrees[i], compTrees[j]);}}int compBest = 0;// 小分量用状态压缩DPif (compSize <= 15) {compBest = dpComp(compTrees, compConflict);} // 大分量用DFS+剪枝else {// 计算后缀和(从i开始的最大可能和)vector<int> suffix(compSize, 0);suffix[compSize-1] = compTrees.back().r * compTrees.back().r;for (int i = compSize-2; i >= 0; --i) {suffix[i] = suffix[i+1] + compTrees[i].r * compTrees[i].r;}vector<bool> selected(compSize, false);dfsComp(compTrees, compConflict, selected, 0, 0, compBest, suffix);}totalSum += compBest;}cout << totalSum << endl;return 0;
}

代码解析

  1. ​冲突检测优化​​:

    • 使用distSq计算圆心距平方(整数运算避免浮点误差)
    • isConflict通过圆心距² < (r₁ + r₂)²判断冲突
  2. ​连通分量分解​​:

    • findComponents用BFS将树分组
    • 不同分量完全独立,减少搜索空间
  3. ​混合求解策略​​:

    • ​≤15节点​​:状态压缩DP(dpComp),用位掩码表示选择状态
    • ​>15节点​​:DFS(dfsComp)配合后缀和剪枝
  4. ​关键优化点​​:

    • 按半径降序排序(使剪枝更早生效)
    • 后缀和数组(快速计算剩余最大可能值)
    • 状态压缩DP(高效处理小分量)
  5. ​时间复杂度​​:

    • 最坏情况:O(2^(n/2))(优于朴素O(2^n))
    • 平均情况:O(n² + k·2^(m))(m为最大分量大小)

实例验证

输入样例:
6
1 1 2
1 4 2
1 7 2
4 1 2
4 4 2
4 7 2
执行过程:
  1. ​连通分量分解​​:6棵树全连通(因(1,1)与(4,1)冲突)
  2. ​分量求解​​:
    • 分量大小6 ≤ 15 → 状态压缩DP
    • 有效组合:{(1,1,2), (1,7,2), (4,4,2)}
    • 半径平方和 = 2² + 2² + 2² = 12
  3. ​输出结果​​:12 ✓
其他测试:
测试场景输入特征输出验证结果
单棵树[(0,0,5)]25
全冲突[(0,0,1),(0,0,2),(0,0,3)]9
无冲突[(0,0,1),(3,0,1),(6,0,1)]3
链式冲突[(0,0,2),(0,3,2),(0,6,2)]8

注意事项

  1. ​精度处理​​:

    • 全程使用整数运算(圆心距²和半径和²)
    • 避免浮点数比较误差
  2. ​边界条件​​:

    • 单棵树直接返回r²
    • 空输入返回0
    • 全冲突时选最大单树
  3. ​特殊场景​​:

    • 圆心重合时:任意两棵树都冲突
    • 超大半径树:可能"吞并"周围所有树
    • 分散小树群:独立分量加速处理

测试点设计

测试类型测试数据验证重点
功能测试示例输入基础功能
边界测试n=1, n=30极端输入
冲突测试全冲突/无冲突选择逻辑
精度测试临界距离(r₁+r₂)²±1冲突判断
性能测试n=30随机数据运行时间≤1s

优化建议

  1. ​迭代加深搜索​​:

    // 限制深度逐步增加
    for (int depth = 1; depth <= maxDepth; depth++) {if (dfsWithDepthLimit(...)) break;
    }
  2. ​启发式排序​​:

    // 按冲突度排序(高冲突树优先)
    sort(trees.begin(), trees.end(), [&](Tree a, Tree b) {return conflictCount[a.id] > conflictCount[b.id];
    });
  3. ​并行计算​​:

    #pragma omp parallel for
    for (auto& comp : components) {solveComponent(comp);
    }
  4. ​记忆化搜索​​:

    unordered_map<string, int> memo; // 状态缓存
http://www.dtcms.com/wzjs/115845.html

相关文章:

  • 哪些网站是用asp.net开发的口碑营销的前提及好处有哪些
  • 云南网站建设公司前十名百度seo报价
  • 金融网站建设方案网站模板及源码
  • 做我女朋友网站p0rn视频杭州疫情最新消息
  • 做门户网站公司最新nba排名
  • 网站怎样设计网页网络营销是什么
  • 惠州高端网站建设服务南宁seo排名优化
  • 网站前台页面的设计与实现外贸网站外链平台
  • 网站去公安局备案流程深圳市企业网站seo营销工具
  • 公司网站建设步骤seo网络优化是什么工作
  • 网站建设项目规划书社团宣传优化网站搜索
  • 天津网站制作计划鞍山做网站的公司
  • 建设机械网站制作最好的seo外包
  • 合肥网站建设xbuw网络营销学什么内容
  • 药品网站前置审批seo思维
  • 杭州房地产网站建设外国网站怎么进入
  • 长沙环路建设开发有限公司网站企业如何建站
  • 网站文章的作用重庆白云seo整站优化
  • 刘家窑做网站的公司seo排名点击工具
  • bootstrap 购物网站 导航菜单越秀seo搜索引擎优化
  • wordpress表情按钮搜索引擎优化论文3000字
  • 怎么自己免费做网站微信朋友圈广告投放代理
  • 白小姐生肖做特网站软件制作
  • 利用c 做网站关键词优化排名公司
  • 医疗网站被黑后可以做排名网络营销策划方案范文
  • 地产网站怎么做马鞍山网站seo
  • 深圳集团网站建设win10系统优化软件哪个好
  • 代理网站下载查权重
  • 建设局工程网站seo短视频网页入口引流下载
  • 网站制作教程书籍学校seo推广培训班