7.19练习题解
题解
A
解法
手推大样例得到作法:
先从当前状态变成所有对角线都是从一发出的状态,再从这个状态变成答案状态即可。
code
\(\tiny 没有诶嘿嘿\)
B
解法:
考虑暴力枚举。
用 \(O(n^2m^2)\) 的时间枚举两个装置的位置,再用 \(O(k)\) 的时间计算答案。
复杂度 \(O(n^2m^2k)\)。
然后发现跑满有 \(10^9\),再加上xyd的评测姬菜得要死,这个做法会被卡成70分。
然后就可以考虑优化。我们现在确定了一个装置 \(A\) 的位置,并对 \(A\) 求答案。
可以先用一个set存装置放各种位置的答案,再用这个去加上 \(A\) 的答案。
但是有些情况与 \(A\) 会有重复,答案会改变,不能直接加。于是我们考虑枚举与 \(A\) 有重复的情况。
不难发现,我们只用枚举 \(A\) 的哪一个位置和另一个装置的哪一个位置冲突即可,即 \(O(k^2)\)。
这时我们将set中另一个装置原来的答案删去再算出他与 \(A\) 冲突完的答案,在 \(A\) 计算完了答案后再把另一个答案在set中的答案还原即可。
总结:\(O(nm)\) 枚举 \(A\) 的位置,用 \(O(k^2)\) 的时间枚举另一个装置的位置并用 \(O(\log n)\) 的时间更改set中的答案(这个复杂度最后被覆盖了),最后用 \(O(k)\) 的时间计算答案,总复杂度 \(O(nmk^3)\)。
code
\(\tiny 别想贺代码自己写去吧诶嘿嘿\)
C
签到题。
\(\tiny 没签到555\)
解法:
动态规划。设 \(dp[i]\) 为前 \(i\) 个最优的答案,\(s[i]\) 为前缀和。
在不选 \(a[i]\) 时
在选 \(a[i]\) 时,考虑枚举 \(j+2\) 作为这一段的开头,所以可以从 \(dp[j]\) 转移。
其中 \(dp[j]-s[j+1]\) 直接线段树维护即可,复杂度 \(O(n\log n)\)。
当然你想的话可以用单调队列直接 \(O(n)\)。
code
\(\tiny 太好写了不放了诶嘿嘿\)
D
神秘二分答案
解法
二分答案。二分最大美观度 \(x\)。不(hen)难发现对于任何 \(i\),只要 \(a[i]\le \frac{x}{2}\),\(a[i]\) 就一定可以选。剩下的数可以在两个已选的 \(a[i]\) 中间夹着,但两个已选的中间最多夹一个。大小判断一下即可。
code
终于有了!
//
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=5e5+5;
int a[MAXN];
int tid,n,m;
vector<int> v;
bool check(int x){
v.clear();
for (int i=1;i<=n;i++)
if (a[i]<=x/2)
v.push_back(i);
if (v.empty()){
bool fg=0;
for (int i=1;i<=n;i++)
if (a[i]<=x)
fg=1;
return (m<=fg);
}
else{
int cnt=0;
for (int i=1;i<v.size();i++){
int minn=1e18;
for (int j=v[i-1]+1;j<v[i];j++) minn=min(minn,a[j]);
if (minn+a[v[i]]<=x and minn+a[v[i-1]]<=x)
cnt++;
}
int minn=1e18;
for (int i=1;i<v[0];i++) minn=min(minn,a[i]);
for (int i=v[v.size()-1]+1;i<=n;i++) minn=min(minn,a[i]);
if (minn+a[v[0]]<=x and minn+a[v[v.size()-1]]<=x) cnt++;
return (cnt+v.size()>=m);
}
}
signed main(){
// freopen("necklace.in","r",stdin);
// freopen("necklace.out","w",stdout);
scanf("%lld %lld %lld",&tid,&n,&m);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
int l=0,r=2e9,ans=0;
while (l<=r){
int mid=(l+r)/2;
if (check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%lld",ans);
return 0;
}

浙公网安备 33010602011771号