1. 程式人生 > >Codeforces contest 1057 C - Tanya and Colored Candies —— spfa+dp

Codeforces contest 1057 C - Tanya and Colored Candies —— spfa+dp

There are n candy boxes in front of Tania. The boxes are arranged in a row from left to right, numbered from 1 to n. The i-th box contains ri candies, candies have the color ci (the color can take one of three values ​​— red, green, or blue). All candies inside a single box have the same color (and it is equal to ci).

Initially, Tanya is next to the box number s. Tanya can move to the neighbor box (that is, with a number that differs by one) or eat candies in the current box. Tanya eats candies instantly, but the movement takes one second.

If Tanya eats candies from the box, then the box itself remains in place, but there is no more candies in it. In other words, Tanya always eats all the candies from the box and candies in the boxes are not refilled.

It is known that Tanya cannot eat candies of the same color one after another (that is, the colors of candies in two consecutive boxes from which she eats candies are always different). In addition, Tanya’s appetite is constantly growing, so in each next box from which she eats candies, there should be strictly more candies than in the previous one.

Note that for the first box from which Tanya will eat candies, there are no restrictions on the color and number of candies.

Tanya wants to eat at least k candies. What is the minimum number of seconds she will need? Remember that she eats candies instantly, and time is spent only on movements.

Input
The first line contains three integers n, s and k (1≤n≤50, 1≤s≤n, 1≤k≤2000) — number of the boxes, initial position of Tanya and lower bound on number of candies to eat. The following line contains n integers ri (1≤ri≤50) — numbers of candies in the boxes. The third line contains sequence of n letters ‘R’, ‘G’ and ‘B’, meaning the colors of candies in the correspondent boxes (‘R’ for red, ‘G’ for green, ‘B’ for blue). Recall that each box contains candies of only one color. The third line contains no spaces.

Output
Print minimal number of seconds to eat at least k candies. If solution doesn’t exist, print “-1”.

Examples
inputCopy
5 3 10
1 2 3 4 5
RGBRR
outputCopy
4
inputCopy
2 1 15
5 6
RG
outputCopy
-1
Note
The sequence of actions of Tanya for the first example:

move from the box 3 to the box 2;
eat candies from the box 2;
move from the box 2 to the box 3;
eat candy from the box 3;
move from the box 3 to the box 4;
move from the box 4 to the box 5;
eat candies from the box 5.
Since Tanya eats candy instantly, the required time is four seconds.

題意:

有n個排成一排的糖,起始位置為s,吃掉一個位置的所有糖不需要時間,往左或右移一步需要1的時間,他只會吃比上次吃位置更多糖的位置的糖,問你最少花掉多少時間。舉個例子,1 2 3 4 5 當他吃了1之後可以隨便吃其他的地方,吃了4之後只能吃5或者不吃。

題解:

這個可以用最短路做,先把所有點都放到佇列裡,假設是從那個位置開始的,dp[i][j]表示在第i個位置吃了j個糖果需要走的最少路程。由於每次都吃比當前位置所有的糖的數量大的那個位置的糖,那麼就不需要擔心原來的位置會被重複走。

#include<bits/stdc++.h>
using namespace std;
#define pa pair<int,int>
#define mp(a,b) make_pair(a,b)
const int inf=1e9;
int v[55],dp[55][2505],inq[55][2505];
char col[55];
int main()
{
    int n,s,k;
    scanf("%d%d%d",&n,&s,&k);
    for(int i=1;i<=n;i++)
        scanf("%d",&v[i]);
    scanf("%s",col+1);
    queue<pa>Q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=2500;j++)
            dp[i][j]=inf;
    for(int i=1;i<=n;i++)
    {
        int dis=abs(i-s);
        dp[i][v[i]]=dis;
        Q.push(mp(i,v[i]));
        inq[i][v[i]]=1;
    }
    while(!Q.empty())
    {
        int pos=Q.front().first,val=Q.front().second;
        Q.pop();
        for(int i=1;i<=n;i++)
        {
            if(v[i]>v[pos]&&col[i]!=col[pos])
            {
                if(dp[i][val+v[i]]>dp[pos][val]+abs(i-pos))
                {
                    dp[i][val+v[i]]=dp[pos][val]+abs(i-pos);
                    if(inq[i][val+v[i]])
                       continue;
                    Q.push(mp(i,val+v[i]));
                }
            }
        }
    }
    int ans=inf;
    for(int i=1;i<=n;i++)
    {
        for(int j=k;j<=2500;j++)
            ans=min(ans,dp[i][j]);
    }
    printf("%d\n",ans==inf?-1:ans);
    return 0;
}