IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 洛谷 小木棍(暴力+剪剪剪剪枝) -> 正文阅读

[数据结构与算法]洛谷 小木棍(暴力+剪剪剪剪枝)

题目链接:

小木棍 - 洛谷

思路:

如果只考虑暴力,做法很简单,枚举所有可能的最终长度,都跑一遍dfs,取最小结果即可,本题难就难在大量的剪枝,具体见代码。

我的思路也是参考了大佬的博客:题解 P1120 【小木棍 [数据加强版]】 - Kaori 的博客 - 洛谷博客

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 70;
int n, x, sum=0;
int m, len; //要拼的木棍数量,长度
int a[maxn], cnt;
bool used[maxn];
bool ok = false; //当前是否拼接成功
bool cmp(int i,int j) {return i>j;}
void dfs(int cur, int last, int rest){ //当前拼的数量,最后用的木棍编号,剩下要拼的长度
    if(rest==0){
        if(cur==m) {ok=1; return;}
        int i;
        for(i=1; i<=cnt; i++)
            if(!used[i]) break;
        used[i] = 1;
        dfs(cur+1, i, len-a[i]);
        used[i] = 0;
        if(ok) return; //如果成功,直接返回
    }
    //二分查找第一个长度不大于rest的木棍
    int left = last+1, right = cnt, mid;
    while(left < right){
        mid = (left+right)>>1;
        if(a[mid]<=rest) right = mid;
        else left = mid+1;
    }
    //注意从left开始,这点很重要(从长到短逐个选择,保证顺序和灵活性)
    for(int i=left; i<=cnt; i++){
        if(used[i] || a[i]>rest) continue; //用过的或者太长的不能用
        if(!used[i-1]&&a[i]==a[i-1]) continue; //和前面等长,前面不能过,这个也不能
        used[i] = 1;
        dfs(cur,i,rest-a[i]);
        used[i] = 0;
        if(ok) return; //如果成功,直接返回

        if(rest==a[i] || rest==len) return; //特殊优化
    }
}
int main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i=1; i<=n; i++){
        cin>>x;
        if(x<=50) {a[++cnt] = x; sum += x;}
    }
    sort(a+1,a+n+1,cmp); //排序优化,短木棍更加灵活,排在后面,取的时候先拿长的再拿短地
    for(len=a[1]; len<=sum/2; len++){
        if(sum%len != 0) continue; //不是整倍数,必定合不出来
        m = sum/len; //要拼的木棍数量
        ok = 0; 
        used[1] = 1;
        dfs(1,1,len-a[1]);
        used[1] = 0;
        if(ok) {cout<<len; return 0;}
    }
    cout<<sum;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-04 13:41:41  更:2021-12-04 13:43:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:34:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码