2021.7.16 2021.7.16 2021.7.16 模拟赛 Ⅵ Ⅵ Ⅵ
目录:
T1.有趣的家庭菜园4
T2.屠龙勇士
T3.周长
T4.管道监控
T 1 : T1: T1:有趣的家庭菜园 4 4 4
l
u
o
g
u
luogu
luogu
l
i
n
k
link
link
分析:
本来还以为是单峰函数(
显然前后缀和了 不过是单峰的 所以还要
+
1
+1
+1
因为最小代价就是它们的差 从前面浇水到峰的后面 也可以使峰后半段的差距减小
从后面浇水同理
然后就在前后缀和里取最大 再取
m
i
n
min
min即可
CODE:
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int n,a[N];
ll sum[N],suf[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=2;i<=n;i++)
sum[i]=sum[i-1]+max(0,a[i-1]-a[i]+1);
for(int i=n-1;i>=1;i--)
suf[i]=suf[i+1]+max(0,a[i+1]-a[i]+1);
ll ans=1e18;
for(int i=1;i<=n;i++)
ans=min(ans,max(sum[i],suf[i]));
printf("%lld",ans);
return 0;
}
T 2 : T2: T2:屠龙勇士
l
u
o
g
u
l
i
n
k
luogu~link
luogu link
分析:
拓展拓展中国剩余定理好题(
s
o
l
u
t
i
o
n
b
l
o
g
l
i
n
k
solution~blog~link
solution blog link
T 3 : T3: T3:周长
分析:
40
%
40\%
40% 全排列里取最大周长
100
%
100\%
100% 状压
d
p
dp
dp
f
i
,
j
f_{i,j}
fi,j表示状态为
i
i
i 位置在
j
j
j的最小
s
u
m
sum
sum
f
i
,
j
+
m
i
n
(
a
j
,
a
k
)
=
f
i
∣
1
<
<
(
k
−
1
)
,
k
f_{i,j}+min(a_j,a_k)=f_{i|1<<(k-1),k}
fi,j+min(aj,ak)=fi∣1<<(k−1),k
最后统计的时候 转移到
f
2
n
−
1
,
n
f_{2^n-1,n}
f2n−1,n就好了
这样统计出来的是相交的长度总和 所以最后要用不相交时长度总和减掉 再加上下底长
n
n
n
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define reg register
using namespace std;
const int N=16,inf=0x7fffffff;
int n,a[N],b[N],In;
struct qaq{
long long val,St;
}f[1<<N][N];
int main(){
scanf("%d",&n);
qaq ans=(qaq){inf,0};
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
In+=(a[i]<<1);
}
for(reg int i=0;i<(1<<n);i++)
for(reg int j=1;j<=n;j++)
f[i][j]=(qaq){inf,0};
for(reg int i=1;i<=n;i++)
f[1<<(i-1)][i]=(qaq){0,1};
for(reg int i=0;i<(1<<n);i++)
for(reg int j=1;j<=n;j++)
if(-i-1&(1<<(j-1)))
for(reg int k=1;k<=n;k++)
{
if(-i-1&(1<<(k-1))) continue;
if(f[i][k].val+min(a[j],a[k])==f[i|(1<<(j-1))][j].val)
f[i|(1<<(j-1))][j].St+=f[i][k].St;
else if(f[i][k].val+min(a[j],a[k])<f[i|(1<<(j-1))][j].val)
f[i|(1<<(j-1))][j]=(qaq){f[i][k].val+min(a[j],a[k]),f[i][k].St};
}
for(int i=1;i<=n;i++)
{
if(ans.val==f[(1<<n)-1][i].val)
ans.St+=f[(1<<n)-1][i].St;
else if(ans.val>f[(1<<n)-1][i].val)
ans=f[(1<<n)-1][i];
}
printf("%lld %lld\n",In-(ans.val<<1)+(n<<1),ans.St);
return 0;
}
T 4 : T4: T4:管道监控
分析:
树形
d
p
dp
dp 也可以在
t
r
i
e
trie
trie上面跑费用流
爬了