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. pg_ctl - 启动,停止和重启 PostgreSQL 服务器

    SYNOPSIS pg_ctl start [ -w ] [ -s ] [ -D datadir] [ -l filename] [ -o options] [ -p path] pg_ctl sto ...

  2. Linux ssh内置sftp配置说明

    centos7 环境下已验证 首先建立两个用户,用于sftp访问使用. eg: useradd -d /opt/sftp  -s /bin/nologin sftp 说明 -s /bin/nologi ...

  3. 命令行界面CLI

    1.hive   -e --执行一个或多个查询 hive -e "select * from student limit 3" 2. hive -e     > 将临时查询保 ...

  4. 前端每日实战:37# 视频演示如何把握好 transition 和 animation 的时序,创作描边按钮特效

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/mKdzZM 可交互视频教程 此视频 ...

  5. CodeChef Max-digit Tree(动态规划)

    传送门. 题解: 最主要的问题是如何判断一个数是否合法,这就需要发现性质了. 这个状态划分还是不太容易想到, 每次加的数\(∈[0,k)\),也就是个位一直在变变变,更高的位每次都是加一,这启发我们状 ...

  6. IP释放、更新、以及清除DNS

    此篇文章会带您进行DNS释放.更新以及清除步骤,并协助您就解决您网络方面问题.请在下方选择您所使用的操作系统. Windows 8 在桌面按住Windows + X按键. 选择Command Prom ...

  7. Solr核心(内核)

    Solr核心(内核)   Solr核心(Core)是Lucene索引的运行实例,包含使用它所需的所有Solr配置文件.我们需要创建一个Solr Core来执行索引和分析等操作. Solr应用程序可以包 ...

  8. 去掉xcode中警告的一些经验

    1.编译时,编译警告忽略掉某些文件 只需在在文件的Compiler Flags 中加入 -w 参数,例如: 2.编译时,编译警告忽略掉某段代码 #pragma clang diagnostic pus ...

  9. scrapy xpath xpath('---').xpath('string(.)') 提取子元素全部文本

    product.xpath("div//div[@class='a-row a-spacing-mini'][1]/div[2]").xpath('string(.)')

  10. 网路编程之socket与 socketserver、黏包

    socket与socketerver才是我们学习python中网络编程的重中之重在介绍他们两个之前我先介绍一些相关知识 一.socket 概念 咱们现在ois模型中找到socket所承担的角色 soc ...