Garlands
2024-08-28 17:21:36
题意:
n个数分成m段,每段偶数个数,最小化和最大段的半个区间的数字和。
分析:
先想到了二分,dp求能分成的最小段数。
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
const ll INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod = ;
int dp[][],sum[],n,m,d;
int judge(int x){
dp[][]=;
dp[][]=INF;
for(int i=;i<=n;++i){
dp[i][]=dp[i][]=INF;
for(int l=;l<=d&&(i-*l)>=;++l){
if(sum[i]-sum[i-l]>x)break;
if(sum[i-l]-sum[i-*l]<=x){
dp[i][]=min(dp[i][],dp[i-*l][]+);
dp[i][]=min(dp[i][],dp[i-*l][]+);
}
}
}
return dp[n][(m-)%]>m-;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&d);
int a;
sum[]=;
for(int i=;i<=n;++i)
{
scanf("%d",&a);
sum[i]=sum[i-]+a;
}
if(n%||n<*(m-)||n>*d*(m-))
{
printf("BAD\n");continue;
}
int l=,r=sum[n];
while(l<=r){
int mid=(l+r)>>;
if(judge(mid))l=mid+;
else r=mid-;
}
printf("%d\n",l);
}
return ;
}
最新文章
- PHP常用函数总结
- 初接触BurpLoader工具
- flask请求管道
- delphi TIdHTTP Post乱码问题
- [[4], [5, 6, 7]](Python)list的方法
- 算法教程(3)zz
- microsoft azure 速度测试网址
- Ubuntu14.04建立WiFi热点
- 转载:win7JDK环境配置
- 利用查询提示优化SQL
- mongodb进阶一之高级查询
- javascript 学习总结(六)RegExp对象
- 真正实现Netty私有协议开发
- Android 根据字符串动态获取资源ID
- EBS开发技术之trace
- XML学习总结二&mdash;&mdash;DTD
- 逆向知识第一讲,IDA的熟悉使用
- odoo订餐系统之订单设计
- ASP.NET 网站管理工具
- 配置svn用户及密码