Codeforces Round #765 补题 3/6
A. Ancient Civilization
题意:给出一个长度为
n
n
n的数组
x
x
x和限制
k
k
k,定义一个函数
d
(
x
,
y
)
d(x,y)
d(x,y),其意义是
x
x
x和
y
y
y在二进制表示下的不同位数的和,寻找一个数
y
y
y使得
s
u
m
(
x
i
,
y
)
(
1
≤
i
≤
n
)
sum(x_ i,y)(1 \leq i \leq n)
sum(xi,y)(1≤i≤n)最小
保证一定能找到某个数使得不同位数的总和小于等于
k
k
k
统计一下数组中第 i i i位为1的个数,若大于 n / 2 n / 2 n/2,则该位为1,反之,为0
#include<bits/stdc++.h>
using namespace std;
const int N = 35;
int cnt[N];
void solve(){
memset(cnt,0,sizeof cnt);
int n,k;
cin>>n>>k;
for(int i = 1;i <= n;i ++ ){
int x;
cin>>x;
for(int j = 0;j <= 30;j ++ ){
if((x >> j) & 1){
cnt[j] ++;
}
}
}
int ans = 0;
for(int i = 30;i >= 0;i -- ){
int te = 0;
if(cnt[i] > n / 2){
te = 1;
}
ans = ans * 2 + te;
}
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t -- )
solve();
}
B. Elementary Particles
题意:给出一个长度为 n n n的数组 x x x,将 x x x分为两个长度相等的子数组( l e n g t h < n length<n length<n),且这两个子数组在某一位上的数字相同,求最长的子数组长度
寻找每一个数字下次再次出现的最小下标 y y y,长度就等于( x − y + n x - y + n x−y+n),取最大值即可
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
int a[N];
void solve(){
memset(a,0,sizeof a);
int n;
cin>>n;
int ans = 0;
for(int i = 1;i <= n;i ++ ){
int x;
cin>>x;
//cin>>a[i];
if(a[x]){
ans = max(ans,a[x] - i + n);
}
a[x] = i;
}
if(ans == 0) cout<<"-1\n";
else cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t -- )
solve();
}
C. Road Optimization
题意:在一条长度为 l l l的公路上,有 n n n个限速标志,表示在第 d i d_i di处有一个速度限制 a i a_i ai,现最多可以拆除 k k k个限速标志,给出通过这条公路的最短时间(不可以拆除第一个标志)
dp
假设走到第
i
i
i个标志时,前方一共有
j
j
j个标志,则后方可以选择拆除前方的标志或者不拆除
则
f
[
t
]
[
j
+
1
]
=
m
i
n
(
f
[
t
]
[
j
+
1
]
,
f
[
i
]
[
j
]
+
a
[
i
]
∗
(
d
[
t
]
−
d
[
i
]
)
)
f[t][j + 1] = min(f[t][j + 1],f[i][j] + a[i] * (d[t] - d[i]))
f[t][j+1]=min(f[t][j+1],f[i][j]+a[i]∗(d[t]−d[i]))
#include<bits/stdc++.h>
using namespace std;
const int N = 505;
int f[N][N],a[N],d[N];
void solve(){
int n,l,k;
cin>>n>>l>>k;
memset(f,0x3f3f3f3f,sizeof f);
d[n + 1] = l;
for(int i = 1;i <= n;i ++ ){
cin>>d[i];
}
for(int i = 1;i <= n;i ++ ){
cin>>a[i];
}
f[1][0] = 0;
for(int i = 1;i <= n;i ++ ){
for(int j = 0;j < i;j ++ ){
for(int t = i + 1;t <= n + 1;t ++ ){
f[t][j + 1] = min(f[t][j + 1],f[i][j] + a[i] * (d[t] - d[i]));
}
}
}
int ans = 1e9;
for(int i = n - k;i <= n;i ++ ){
ans = min(ans,f[n + 1][i]);
}
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
solve();
}