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 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> hdu No.5248 序列变换(二分+贪心) -> 正文阅读

[Java知识库]hdu No.5248 序列变换(二分+贪心)

题目链接:https://acm.dingbacode.com/showproblem.php?pid=5248

序列变换

*Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3527 Accepted Submission(s): 1288
*

Problem Description

给定序列A={A1,A2,…,An}, 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:Bi<Bi+1,1≤i<N)。

我们定义从序列A到序列B变换的代价为cost(A,B)=max(|Ai?Bi|)(1≤i≤N)。

请求出满足条件的最小代价。

注意,每个元素在变换前后都是整数。

Input

第一行为测试的组数T(1≤T≤10).

对于每一组:
第一行为序列A的长度N(1≤N≤105),第二行包含N个数,A1,A2,…,An.
序列A中的每个元素的值是正整数且不超过106。

Output

对于每一个测试样例,输出两行:

第一行输出:“Case #i:”。i代表第 i 组测试数据。

第二行输出一个正整数,代表满足条件的最小代价。

Sample Input

2
2
1 10
3
2 5 4

Sample Output

Case #1:
0
Case #2:
1

Source

2015年百度之星程序设计大赛 - 初赛(1)

题解

因为题目是求的最小代价,所以假设最小的代价是res,那么很容易得到

  • 如果这时候的代价是在[0,res)范围之内,一定不会满足要求
  • 如果代价在[res, 1e6] (因为题目的数据最大是1e6,所以最大到11e6即可) 之内,一定是满足要求的

根据这个来二分求解即可,需要用个check函数判断当前代价是否能满足要求(用贪心判断)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int nums[100010];
int nums1[100010];

bool check(int n, int diff){
    //贪心,第一个先最大程度的减少
    nums1[1] = nums[1] - diff;
    for(int i = 2;i <= n;++i){
        if(nums1[i] >= nums1[i-1]){
            //增大nums1[i]到刚好nums1[i-1] + 1的位置保证递增
            nums1[i] = min(max(nums1[i - 1] + 1,nums[i] - diff),nums[i] + diff);
        }else{
            //减少nums1[i]到刚好nums1[i-1] + 1的位置保证递增
            nums1[i] = max(min(nums1[i - 1] + 1,nums[i] + diff),nums[i] - diff);
        }
        if(nums1[i-1] >= nums1[i]){
            return 0;
        }
    }
    return 1;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int T;
    cin >> T;
    int tt = 1;
    while(T--){
        int n;
        cin >> n;
        for(int i = 1;i <= n;++i){
            cin >> nums[i];
        }
        //二分
        int l = 0;
        int r = 1e6;
        int mid;
        while(l < r){
            mid = (r - l) / 2 + l;
            if(check(n,mid)){
                r = mid;
            }else{
                l = mid + 1;
            }
        }
        cout << "Case #" << tt++ << ":" << endl;
        cout << l << endl;
    }
	return 0;
}

最后,关于二分我好像想通了为什么为什么二分老是会卡在r - l == 1的地方死循环,

  • 如果下面是l = midr = mid - 1的话,求mid应该是mid = (l - r) / 2 + r
  • 如果下面是l = mid + 1r = mid的话,求mid应该是mid = (r - l) / 2 + l
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-07-22 14:00:25  更:2021-07-22 14:04:10 
 
开发: 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年12日历 -2024/12/18 17:38:27-

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