ZOJ 2972 Hurdles of 110m

简单DP。dp[i][j]表示完成第i段,有j体力的情况下,获得的最小时间,

然后就可以递推:

//高速跑
if(j-s[i].f1>=0)
dp[i][j-s[i].f1]=min(dp[i][j-s[i].f1],dp[i-1][j]+s[i].t1);

//中速跑
dp[i][j]=min(dp[i][j],dp[i-1][j]+s[i].t2);

//低速跑
dp[i][min(m,j+s[i].f2)]=min(dp[i][min(m,j+s[i].f2)],dp[i-1][j]+s[i].t3);

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

int T;
const int maxn=100+20;
int dp[maxn][maxn];
int n,m;
struct X
{
    int t1,t2,t3;
    int f1,f2;
}s[maxn];

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d%d%d%d%d",&s[i].t1,&s[i].t2,&s[i].t3,&s[i].f1,&s[i].f2);
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++)
                dp[i][j]=0x7fffffff;

        //中速过
        dp[1][m]=min(dp[1][m],s[1].t2);
        //高速过
        if(m-s[1].f1>=0) dp[1][m-s[1].f1]=min(dp[1][m-s[1].f1],s[1].t1);
        //低速过
        dp[1][m]=min(dp[1][m],s[1].t3);

        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                if(dp[i-1][j]!=0x7fffffff)
                {
                    //高速跑
                    if(j-s[i].f1>=0)
                        dp[i][j-s[i].f1]=min(dp[i][j-s[i].f1],dp[i-1][j]+s[i].t1);

                    //中速跑
                    dp[i][j]=min(dp[i][j],dp[i-1][j]+s[i].t2);

                    //低速跑
                    dp[i][min(m,j+s[i].f2)]=min(dp[i][min(m,j+s[i].f2)],dp[i-1][j]+s[i].t3);
                }
            }
        }
        int ans=0x7fffffff;
        for(int i=0;i<=m;i++) ans=min(ans,dp[n][i]);
        printf("%d\n",ans);
    }

    return 0;
}

 

你可能感兴趣的:(ZOJ 2972 Hurdles of 110m)