跳格子(Nikola)

【问题描述】
    Tom现在已经成为一个游戏里的重要人物。
    这个游戏界面包含一行N个方格,N个方格用1到N的数字表示。Nikola开始是在1号位置,然后能够跳到其他的位置,Tom的第一跳必须跳到2号位置。随后的每一跳必须满足两个条件:

    1.如果是向前跳,必须比前面一跳多跳一个方格。

    2.如果是向后跳,必须和前面一跳一样远。
    比如,在第一跳之后(当在2号位置时),Tom能够跳回1号位置,或者向前跳到4号位置。

    每次他跳入一个位置,Tom必须支付相应的费用,Tom的目标是从1号位置尽可能便宜地跳到N号位置。
    请你写一个程序,看看Tom跳到N号位置需要的最少花费是多少。

【输入格式】
    输入一共有N+1行

    第1行:包含一个整数N(2<=N<=1000),它是位置的数量
    第2-N+1行:第i+1行表示第i个方格的费用,是一个正整数(不超过500)。

【输出格式】
    输出一个参数,表示Tom跳到N号位置时需要的最少花费。

【输入样例1】                                         【输入样例2】
    6                                                             8

    1 2 3 4 5 6                                              2 3 4 3 1 6 1 4
【输出样例1】                                         【输出样例2】

    12    【2-1-3-6】                                    14      【2-4-7-4-8】

    这道题楼楼第一反应就是回溯暴力……然后……华丽丽地70……【暴力不可取,但骗分很关键】
    这道题正解就是DP,阶段性强和N的取值范围说明复杂度应该是O(n^2),所以想到DP就很简单了。

    状态转移方程:从上个格子往前跳到当前第i格:f[ i ][ j ]=min( f[ i ][ j ], f[ i - j ][ j - 1 ]+value[ i ])
                            从上个格子向后跳到当前第i格:f[ i ][ j ]=min( f[ i ][ j ], f[i + j][ j ]+value[ i ])
    最后对于所有的位于第n个格子的状态取min就是答案

    下面是程序:
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e3+50,INF=0x3f3f3f3f;
    int n,val[N],f[N][N];
    int main()
    {
       cin>>n;
       for(int i=1;i<=n;++i)
         cin>>val[i];
       memset(f,0x3f,sizeof(f));
       f[1][0]=0;
       for(int st=1;st<=n;++st)
       {
        for(int i=st+1;i<=n;++i)
          f[i][st]=min(f[i][st],f[i-st][st-1]+val[i]);
        for(int i=n-st;i>=1;--i)
          f[i][st]=min(f[i][st],f[i+st][st]+val[i]);
       }
       int ans=INF;
       for(int i=1;i<=n;++i)
       {
        ans=min(ans,f[n][i]);
       }
       cout<<ans;
       return 0;
    }

猜你喜欢

转载自blog.csdn.net/g21glf/article/details/80820950