首页 > 其他分享 >hdu:序列划分(构造二分)

hdu:序列划分(构造二分)

时间:2023-05-26 16:33:25浏览次数:48  
标签:二分 hdu 正整数 int res ll cnt 序列

Problem Description
给定\(n\)个正整数\(a_1,a_2,\dots,a_n\),将这个序列从左到右划分成\(m\)段,使得每段至少有一个数。

你需要让数字之和最大的那一段的数字和尽可能得小。

Input
第一行包含一个正整数
T(1≤T≤10),表示测试数据的组数。

每组数据第一行包含两个正整数
n,m(1≤m≤n≤100000)。

第二行包含
n个正整数
​​ (1≤a​i≤10​^9)。

Output
对于每组数据输出一行一个整数,即你找到的方案中,数字之和最大的那一段的数字和。

输入样例
1
6 4
1 5 4 6 2 3
输出样例
6

数学-构造单调函数二分

设函数f(x)表示数字和不大于x至少需要分成f(x)段,则二分寻找最小的x,使得f(x)等于m,注意f(x)相等时如何寻找最小的x

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m;
int a[N];

ll f(ll x)
{
	ll res=0,cnt=1;
	for(int i=1;i<=n;++i)
	{
		if(res+a[i]>x) cnt++,res=0;
		res+=a[i];
	}
	return cnt;
}

ll bina(ll mi,ll ma)//二分的目的:找到最小的x使得f(x)=m
{
	ll l=mi,r=ma,ans=ma;
	while(l<=r)
	{
		ll mid=(l+r)>>1;
		ll tmp=f(mid);
		//cout<<mid<<' '<<tmp<<'\n';
		if(tmp<=m) ans=mid,r=mid-1;//现在想取的是最小的解不断让r向左逼近
		else l=mid+1;
	}
	return ans;
}

void solve()
{
    cin>>n>>m;
    int maxn=0;
    ll sum=0;
    for(int i=1;i<=n;++i) 
    {cin>>a[i];maxn=max(maxn,a[i]);sum+=a[i];}
    cout<<bina((ll)maxn,sum)<<"\n";
    //cout<<f(6)<<"\n";
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        solve();
    }
    return 0;
}

标签:二分,hdu,正整数,int,res,ll,cnt,序列
From: https://www.cnblogs.com/ruoye123456/p/17435097.html

相关文章

  • HDU 1176 免费馅饼(简单动态规划)
    传送门这道题是中文描述的,我相信大家都肯定能够看得懂(滑稽),思路上呢大概就是一个升级版的数塔(点我去看数塔)既然是动态规划问题所以首先肯定要先找出来状态转移方程,我找到的状态转移方程就是a[i][j]+=max(max(a[i+1][j+1],a[i+1][j]),a[i+1][j-1]),其中a[i][j]就是表示第i时刻在k位......
  • HDU 1029 Ignatius and the Princess IV(基础dp)
    传送门题目大意就是给你n个数(保证n为一个奇数),存在一个数出现的次数大于(n+1)/2次,求这个数;这个数出现的次数比其他数出现的次数加起来还多,那么当这个数出现时+1,其他的数出现时-1,最后得到的数为正数。假定一个数为特殊数,若当前数与特殊数相同则cnt++,若不相同则cnt--,如果这时cnt<0,用当......
  • HDU 2084 数塔(动态规划入门)
    传送门中文题就不给大家翻译了(手动滑稽),反正大家都看得懂。这是一道动态规划入门的题目,只需要找出状态转移方程即可。状态方程:dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j])(dp[i][j]表示从第i层第j个数开始搜能得到的最大数)代码如下:#include<cstring>#include<iostream>#include<......
  • HDU 1024 Max Sum Plus Plus(动态规划)
    传送门题意是给你个数字序列,现在让你把这个序列分成m个连续的子序列,且要求这m个子序列的累加和最大。思路:这道题的题意可以理解为问在序列为末尾时,把序列分为m个子序列这个状态时的最大累加和,那么可以得出这个状态应该是由上一个状态转移得来:(因为dp[i][j]表示数到第j个字符时,前j个......
  • 字符串strip方法:只要头尾包含有指定字符序列中的字符就删除
    mystr='\n\tthisisacat\n\r'mystr=mystr.strip()#默认去掉两头的空格、换行符\n,制表符\t、回车符\rprint(mystr)#只要头尾包含有指定字符序列中的字符就删除mystr='1213HelloWord2331'mystr=mystr.strip('123')#strip会把‘123’三个元素中的随便......
  • FLEX4 序列号失效
    愚人节这天,FLASHBUILDER也和大家开了个玩笑,一大早起来,序列号被封了。上网搜了一下,果然天无绝人之路 但是我换了序列号仍然无法使用 再看以下这位高手的:方法1:暂时把系统时间改到2008,启动后再调回现在的时间。方法2:解压后存入Flex的安装文件夹plugins/com.adobe.flexide.amt_4.0.......
  • PyTorch-Forecasting一个新的时间序列预测库
    时间序列预测在金融、天气预报、销售预测和需求预测等各个领域发挥着至关重要的作用。PyTorch-forecasting是一个建立在PyTorch之上的开源Python包,专门用于简化和增强时间序列的工作。在本文中我们介绍PyTorch-Forecasting的特性和功能,并进行示例代码演示。完整文章:https://av......
  • 什么是java序列化?什么情况下需要序列化?
    Java序列化是一种将对象转换为字节流的过程,使得对象可以在网络上传输或存储到文件系统中,同时也可以将字节流重新转换回对象的过程。通过序列化,可以将对象的状态保存下来,并在需要的时候恢复对象的状态。在Java中,通过实现Serializable接口,即可使一个类具备序列化的能力。序列化使用O......
  • 时间序列-1
    时间序列是与时间相关的、一般按时间顺序的一组数字序列。按平稳行可分为平稳时间序列和非平稳时间序列。对于平稳时间序列,一般可以通过ARMA模型进行拟合。对于非平稳时间序列,可以通过差分转化为非平稳时间序列。个人理解:在深度学习中,时间序列因为其含有稀疏特征而可能造成......
  • 最长单调递增子序列
    问题:设计一个O(n^2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。方法一:最长公共子序列,动态规划。思路:1:将数组a复制到b;      2:对b排序;      3:对数组b去重(注意去重是必要的,因为要求单调递增),这里利用hash表去重。        4:求a,b数组......