AGC004B Colorful Slimes

发布时间 2023-10-17 22:07:48作者: 201929

$ {\scr \color {Orchid}{\text{生于尘埃,溺于人海,死于理想高台。}}} $

题目链接:Colorful Slimes

$ {\scr \color {Cyan}{\text{Solution}}} $

分析

思路:挺神奇的$dp$

一个比较显然的结论:最小值的方案中第$2$种操作最多用$n-1$次

证明大概就是一个数用$n-1$次一定会变成另一个数

下面说说$dp$的思路:

$dp[i][j]$表示能用最多$j$次第$2$种操作能变成$a_i$的最小值

假设$a_k$所有可以用最多$j$次第$2$种操作能变成$i$的最小值,则$dp[i][j]=a_k$

举个栗子:

3 1 4 

对于这个$4$来说,用最多$2$次操作能变成坐标为$3$的数最小值,就是$1$

 

如果能理解定义了,那我们接着往下看:

$dp$递推其实并不难,取个$min$比较就行

统计答案怎么做?

我们可以枚举用了几次$2$的操作,后直接相加$dp[1...n][j]$即可

这也是为什么定义方程是“用了j次及以下”的关键qwqq

Code:

//From:201929
#include<bits/stdc++.h>
#define L long long
using namespace std;
L a[2005],dp[2005][2005];
int main()
{
    int n;
    L x;
    scanf("%d%lld",&n,&x);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
    {
        dp[i][0]=a[i];
        for(int j=1;j<n;j++)
        {
            int k=i-j;
            if(k<=0) k+=n;
            dp[i][j]=min(dp[i][j-1],a[k]);
        }
    }
    L minn=1e18+5;
    for(int i=0;i<n;i++)
    {
        L summ=x*i;
        for(int j=1;j<=n;j++) summ+=dp[j][i];
        minn=min(minn,summ);
    }
    printf("%lld",minn);
    return 0;
}