现在有一条 nnn 个点的链,从左到右一字排开,编号为 1,2,…,n1,2,…,n1,2,…,n. 在每条边上,你可以在向左与向右的方向上各打上若干个(可以为 000 个)箭头。
在一个点上,若有 d+d^+d+ 个箭头从该点发出、d−d^−d− 个箭头指向该点,则它的得分为 d−+2d+d^−+2d^+d−+2d+.
现在要求第 iii 个点的得分不小于 aia_iai, 求最少需要的箭头数。
相当于对于每一个 i(1≤i<n)i(1\leq i<n)i(1≤i<n) ,相当于要么 1→ai,2→ai+11\to a_i,2\to a_{i+1}1→ai,2→ai+1 要么 1→ai+1,2→ai1\to a_{i+1},2\to a_i1→ai+1,2→ai。
强制优先选一种方式,比如说后者,用 (2,1)(2,1)(2,1) 表示。
更改方案当且仅当将 (2,1)(2,1)(2,1) 改变为 (1,2)+(1,2)=(2,4)(1,2)+(1,2)=(2,4)(1,2)+(1,2)=(2,4),相当于可以给下一个花 111 的代价加上 333 。
对于一个 333 我们也可以反悔变成 (1,2)+(2,1)=(3,3)(1,2)+(2,1)=(3,3)(1,2)+(2,1)=(3,3),相当于可以给下一个花 111 的代价加上 333,发现有一个 (2,1)(2,1)(2,1) 所以还可以拆成 (1,2)+(1,2)=(2,4)(1,2)+(1,2)=(2,4)(1,2)+(1,2)=(2,4) ,又可以花 111 的代价加一个 333 。
所以现在相当于放 1,2,31,2,31,2,3 ,1,21,21,2 对应具体操作,333 代表反悔。
一次操作 222 可以给下个点一次操作 333 的机会,一次操作 333 可以给下一个点两次操作 333 的机会。
所以放 333 严格比 放 222 要优,放 222严格比放 111 要优。
故贪心从左往右放即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int n,a[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int m=0;
long long ans=0;
for(int i=1;i<=n;i++){
if(a[i]<=0) {m=0;continue;}
int t1=min(a[i]/3,m);m=0;
a[i]-=t1*3;m+=t1*2;ans+=t1;
t1=a[i]/2;a[i]%=2;a[i+1]-=t1,m+=t1;ans+=t1;
if(a[i]) ans++,a[i+1]-=2,a[i]--;
}
printf("%lld\n",ans);
}
博客探讨了一道关于链状结构中箭头配置的问题,目标是确保每个点的得分不小于给定值,同时最小化箭头总数。通过贪心策略,从左至右依次放置箭头,优先选择能带来更多后续操作机会的配置,最终得出最优解。代码实现展示了如何通过贪心算法解决这一问题。
4486

被折叠的 条评论
为什么被折叠?



