1 条题解
-
0
每一种宠物,要么是花 购买的,要么是通过若干次转换获得的。显然答案就是购买的 加上 乘所需转换次数的最大值。
枚举 表示转换次数的最大值,现在我们要选出若干个 直接购买,要找出一个最优策略。
然后我开始饭糖了
我是这么想的:
显然每一个没被选的都要从它前面第一个被选的地方推过来,考虑 DP。设计 表示前 个中,第 个必选且满足条件的最小值。
首先我目测这玩意没法斜率优化,其次他是一个环,我不会求答案,但我知道绝对不是 。
正解
std的思路是,还是先枚举 ,然后每一个 从前面 个找最小值。
这么做保证了是从上一个选择的地方过来的。
证明如下
考虑反证。假设 ,现在假设 从 转移过来,且 选了。
从 而不是 转移过来,说明 ,且 到 之间可以不选别的。这样 可以从 转移过来,不需要选 ,假设不成立。证明毕。
然后这个最小值可以使用 ST 表处理。但注意到这一步的决策包含了上一步的决策,所以我们可以直接维护一个 表示 前 个的最小值。
时间复杂度
#include<bits/stdc++.h> #define int long long #define R(x) x=read() using namespace std; inline int read() { int x=0,y=1; char e=getchar(); while(e>'9'||e<'0') { if(e=='-')y=-1; e=getchar(); } while(e>='0'&&e<='9') { x=(x<<3)+(x<<1)+(e^'0'); e=getchar(); } return x*y; } const int N=2005; int n,x,a[N],ans; int mi[N]; signed main() { freopen("collection.in","r",stdin); freopen("collection.out","w",stdout); R(n),R(x); for(int i=1; i<=n; ++i) { R(a[i]); mi[i]=a[i]; ans+=a[i]; } for(int k=1; k<=n; ++k) { int res=k*x; for(int i=1; i<=n; ++i) { mi[i]=min(mi[i],a[(i+n-k-1)%n+1]); res+=mi[i]; } ans=min(ans,res); } cout<<ans<<"\n"; return 0; }
- 1
信息
- ID
- 448
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 16
- 已通过
- 6
- 上传者