额呵呵naive
【题目分析】
这道题强行让所有的变为最小值都能拿到95分233333333333
因为都是将一个瓶子的值赋给另一个,那么我们可以枚举最后的值。
所以一个瓶子要变化为我们枚举的值,要么直接变为这个值,要么先变成区间最小值,然后再变成这个值,举个小栗子:
比如对于3个数2 7 3,我们要将7变成3,如果直接变代价为21,先变成2再变成3代价为20。
所以记录两个值取min就行了。(还有就是明明有多组数据为什么样例不写一个1啊qwq)
PS:表示不想打第三题了,1.6k是什么玩意儿?
【代码~】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MAXN=310;
const LL INF=1e15;
LL n,cnt,ans;
LL color[MAXN],minn[MAXN][MAXN];
LL pre[MAXN],dp[MAXN][MAXN];
map<LL,LL> ys;
vector<LL> vec[MAXN];
LL Read()
{
LL i=0,f=1;
char c;
for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-')
f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())
i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
void init()
{
memset(minn,0,sizeof(minn));
memset(dp,0,sizeof(dp));
ys.clear();
cnt=0;
}
int main()
{
LL T=Read();
while(T--)
{
init();
n=Read();
for(LL i=1;i<=n;++i)
{
color[i]=Read();
if(!ys[color[i]])
ys[color[i]]=++cnt,vec[cnt].clear();
vec[ys[color[i]]].push_back(i);
pre[i]=pre[i-1]+color[i];
}
for(LL i=1;i<=cnt;++i)
vec[i].push_back(n+1);
for(LL i=1;i<=n;++i)
{
minn[i][i]=color[i];
for(LL j=i+1;j<=n;++j)
minn[i][j]=min(minn[i][j-1],color[j]);
}
for(LL i=1;i<=n;++i)
{
dp[i][ys[color[i]]]=color[i];
for(LL j=1;j<=cnt;++j)
dp[i][j]+=dp[i-1][j];
}
ans=INF;
for(LL i=1;i<=n;++i)
{
LL c=color[i],bef=0;
LL last=0;
for(LL j=0;j<vec[ys[c]].size();++j)
{
LL now=vec[ys[c]][j];
LL sum=pre[now-1]-pre[bef],mn=minn[bef+1][now-1];
LL tmp=ys[mn];
last+=min(sum*c,(sum-(dp[now-1][tmp]-dp[bef][tmp]))*mn+mn*c*(now-bef-1));
bef=vec[ys[c]][j];
}
ans=min(ans,last);
}
cout<<ans<<'\n';
}
return 0;
}