A. DIY Wooden Ladder

题意:有一些不能切的木板,每个都有一个长度,要做一个梯子,求梯子的最大台阶数

做梯子的木板分为两种,两边的两条木板和中间的若干条台阶木板

台阶数为 $k$ 的梯子要求两边的木板长度大于等于 $k+1$ ,中间的木板数等于 $k$。

直接找到最大和次大的木板放两边,剩下的做台阶,设次大的木板长度为 $x$ ,台阶木板数为 $k$ 则答案就是 $min(x-1,k)$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e6+;
int T,n,a[N];
int main()
{
T=read();
while(T--)
{
n=read();
for(int i=;i<=n;i++) a[i]=read();
sort(a+,a+n+);
printf("%d\n",min(a[n-]-,n-));
}
return ;
}

A. DIY Wooden Ladder

B. Pillars

题意:有一排支柱,每个支柱恰好有一个圆盘,每个圆盘的大小各不相同,要求判断是否能把圆盘全部移到一个支柱上

移动的要求:$1.$ 只能移动到相邻圆盘. $2.$ 此支柱只有一个圆盘 $3.$ 要求移动到的支柱上的圆盘大小从下到上保持递减

由于条件 $2$ 和条件 $3$ 显然最终的支柱一定是初始时最大圆盘所在的支柱,然后容易发现最大支柱两边的圆盘大小一定要递减

不然就一定有位置移不动,否则一定可以移得完(每次把当前最大的圆盘一步步移动到最终位置即可)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e5+;
int n,a[N],pos;
int main()
{
n=read();
for(int i=;i<=n;i++)
{
a[i]=read();
if(a[i]>a[pos]) pos=i;
}
bool flag=;
for(int i=pos-;i;i--) if(a[i]>a[i+]) flag=;
for(int i=pos+;i<=n;i++) if(a[i]>a[i-]) flag=;
if(flag) printf("YES\n");
else printf("NO\n");
return ;
}

B. Pillars

C. Array Splitting

题意:一个正整数非减数列 $A$,要分成恰好 $K$ 个非空子序列,最终的价值即为每个子序列最大值与最小值差的和

求最优的划分方案使得总价值最小,输出最小价值

考虑一次划分的贡献,对于第 $0$ 次划分,总价值为 $A[n]-A[1]$(数列非减)

对于第一次划分,设划分位置为 $i,i+1$,则总价值为 $A[i]-A[1]\ +\ A[n]-A[i+1]$

第二次划分,位置为 $j$,不妨设 $j>i$,总价值为 $A[i]-A[1]\ +\ A[j]-A[i+1]\ +\ A[n]-A[j+1]$

发现对于每一次划分的位置 $k$ ,增加的价值比上一次划分多 $A[k]-A[k-1]$(为负数)

所以把所有 $A[i]-A[i+1]$ 排序取前 $K-1$ 小与初始的 $A[n]-A[1]$ 累加即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
// f[i][k]=min a[i]+(f[j][k-1]-a[j+1])
//a[n]-a[1]
//a[i]-a[1]+a[n]-a[i+1]
//a[j]-a[1]+a[i]-a[j+1]+a[n]-a[i+1]
const int N=2e6+;
priority_queue <int,vector<int>,greater<int> > Q;
int n,K,a[N],b[N],ans;
int main()
{
n=read(),K=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<n;i++) b[i]=a[i]-a[i+];
sort(b+,b+n); ans=a[n]-a[];
for(int i=;i<K;i++) ans+=b[i];
printf("%d\n",ans);
return ;
}

C. Array Splitting

D. Yet Another Subarray Problem

题意,给定一个整数列 $A$,要取出一个 '切片' $[l,r]$,切片的价值为 $(\sum_{i=l}^{r}A[i])-k\left \lceil \frac{r-l+1}{m} \right \rceil$

求最大价值

考虑 $m=1$ 时怎么做,显然可以贪心,维护右端点 $i$ 和当前数列的和 $now$ ,每次移动右端点 $i$ ,把 $A[i]-k$ 加入 $now$,如果 $now<0$ 则说明左端点到 $i$ 这一段没有贡献了,直接扔掉,然后 $now=0$,并在每次更新 $now$ 的时候更新全局答案 $ans$

发现考虑把数列每 $m$ 个看成一个块,用同样的方法贪心,发现这样只考虑了左端点在模 $m$ 意义下为 $1$ 的情况,但是因为 $m$ 不大,所以可以直接枚举模 $m$ 意义下左端点的位置,然后分别贪心

注意到右端点也只有考虑到与左端点同余的情况,所以枚举每一个块的时候都要考虑枚举当前右端点在块中的位置,同样更新就好了

看代码可能比较好理解吧...,注意 $long\ long$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=1e6+;
int n,m,K,a[N];
vector <ll> V;//存每个块的和
ll ans;
int main()
{
n=read(),m=read(),K=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=m;i++)//枚举模m意义下的左端点
{
V.clear();
for(int j=i;j<=n;j+=m)//把块的值扔到vector里
{
ll t=;
for(int k=;k<m;k++) t+=a[j+k];
V.push_back(t-K);//记得'-K'
}
ll now=;//当前区间的值
for(int j=;j<V.size();j++)//枚举块
{
int pos=i+j*m; ll nnow=-K;//枚举右端点在当前块中的位置
for(int k=;k<m;k++) { nnow+=a[pos+k]; ans=max(ans,now+nnow); }//移动右端点
now+=V[j]; if(now<) now=;
ans=max(ans,now);
}
}
cout<<ans<<endl;
return ;
}

D. Yet Another Subarray Problem

怎么好像前 $4$ 题都是贪心...

Educational Codeforces Round 69 (Rated for Div. 2) A~D Sloution的更多相关文章

  1. Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

    Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code 题目链接 题意: 给出\(n\)个俄罗斯套娃,每个套娃都有一个\( ...

  2. Educational Codeforces Round 69 (Rated for Div. 2)

                                                                                                  A. DIY ...

  3. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 背包dp

    D. Yet Another Subarray Problem You are given an array \(a_1, a_2, \dots , a_n\) and two integers \( ...

  4. Educational Codeforces Round 69 (Rated for Div. 2) C. Array Splitting 水题

    C. Array Splitting You are given a sorted array

  5. Educational Codeforces Round 69 (Rated for Div. 2)D(DP,思维)

    #include<bits/stdc++.h>using namespace std;int a[300007];long long sum[300007],tmp[300007],mx[ ...

  6. Educational Codeforces Round 69 (Rated for Div. 2) C. Array Splitting (思维)

    题意:给你一个长度为\(n\)的升序序列,将这个序列分成\(k\)段,每一段的值为最大值和最小值的差,求\(k\)段值的最小和. 题解:其实每一段的最大值和最小值的差,其实就是这段元素的差分和,因为是 ...

  7. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】

    一.题目 D. Yet Another Subarray Problem 二.分析 公式的推导时参考的洛谷聚聚们的推导 重点是公式的推导,推导出公式后,分块是很容易想的.但是很容易写炸. 1 有些地方 ...

  8. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  9. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

随机推荐

  1. 08-求解Ax=b:可解性和解的结构

    一.增广矩阵 假设我们要求解方程$Ax=b$,其中矩阵$A$和$b$如下所示: $A = \left[\begin{array}{llll}{1} & {2} & {2} & ...

  2. set unused

    使用 set unused 选项标记不再使用的列 使用 drop unsused columns 丢弃标记为unused的列 alter table tabName set unused column ...

  3. node.js从入门到放弃《什么是node.js》

    1.什么是node.js Node.js是一个后端的Javascript运行环境(支持的系统包括*nux.Windows),这意味着你可以编写系统级或者服务器端的Javascript代码. Node. ...

  4. [CF] E. Camels

    CF 2000 的dp题目还是有点难qwq 题意: 一行有\(n\)个空位,每个空位可以填\([1,4]\)的整数,要求: 1.有\(t\)个位置满足 \(ai−1<ai>ai+1(1&l ...

  5. kafka参数设置

    一.broker参数 broker.id:kafka集群的唯一标识. log.dirs:kafka存储消息日志的目录,多个用逗号隔开,需要保证指定的目录有充足的磁盘空间. zookeeper.conn ...

  6. ubuntu idea 安装

    一.下载 1.进入官网 下载对应安装包 https://www.jetbrains.com/idea/download/#section=linux sudo wget https://downloa ...

  7. django之csrf_exempt解决跨域请求的问题

    一: from django.views.decorators.csrf import csrf_exempt # 获取微信返回的code信息 @csrf_exempt def wechat_auth ...

  8. JIRA之两大统计图讲解

    一.创建与解决的问题-状态统计图 配置方式 理解该统计图 横坐标 x:时间 纵坐标 y:issue数量 统计图示解读: A.随着时间的推移,创建的问题数(红线)减少,修复问题数(绿线)增加,标志着版本 ...

  9. 04 全局配置,java 编意默认版本,1.6.修改配置

    https://www.cnblogs.com/liu-s/p/5371289.html <!-- 修改Intellij Idea 创建maven项目默认Java编译版本 --> < ...

  10. 如何删除发布服务器distribution

    在建立发布服务器后自动生成distribution数据库为系统数据库,drop无法删除,实际删除方法如下:在“对象资源管理器”-“复制”上点击右键,选择“禁用发布和分发”,依次执行即可完成该系统数据库 ...