CF1057C Tanya and Colored Candies

洛谷传送门 CF传送门

Description

给定一个长度为 (n) 的序列,第 (i) 个点的价值为 (r_i) ,颜色为R,B,G其中的一种。

你的初始位置是 (s) ,向左或右移动一步需要花费 (1) 的时间,但是收集某个点的价值不需要时间。

要求是收集点的时候前后两个点的颜色不一样,并且当前点的价值要大于上一个点。

请问收集价值至少为 (k) 的最小时间。

Solution

发现 (nleq 50) ,那么可以瞎搞设计一个DP。

(f_{i,j}) 表示到第 (i) 个位置收集了 (j) 的最小时间。

那么,初始状态为 (f_{i,r_i}=|i-s|) ,转移方程为:

[f_{k,j+r_k}=min_i^{col_i ot =col_k,r_i<r_k}(f_{k,j+r_k},f_{i,j}+|i-k|) ]

注意:因为是至少 (k) 的价值,而 (r_ileq 50) ,所以要枚举 (1)(k+50)

Code

#include<bits/stdc++.h>

using namespace std;
const int N=110,INF=0x3f3f3f3f;
int n,s,m,ans=INF,r[N],f[N][3010];
char col[N];

int main(){
    scanf("%d%d%d",&n,&s,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&r[i]);
    scanf("%s",ch+1);
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=n;i++)   
        f[i][r[i]]=abs(i-s);
    for(int j=1;j<=m+50;j++)
        for(int i=1;i<=n;i++)
            for(int k=1;k<=n;k++)
                if(col[i]!=col[k]&&r[i]<r[k]) f[k][j+r[k]]=min(f[k][j+r[k]],f[i][j]+abs(i-k));
    for(int i=1;i<=n;i++)
        for(int j=m;j<=m+50;j++)
            ans=min(ans,f[i][j]);
    if(ans==INF) puts("-1");
    else printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/jasony/p/14049923.html