HDU1494 跑跑卡丁车 --简单DP

因为是DP专题里面的题目,肯定就是DP了,首先注意到在加速的赛段是不会积攒能量的,而跑几圈也就是相当于把赛道给加长了,没什么本质区别,很容易想到递推式,我用的是三维数组,其实可以压缩到一维,首先,第一位代表当前到达的赛段,第二位表示跑完这一段还有几个加速器,第三位表示跑完这一段还有多少能量,明显只跟前一个赛段有关,所以第一维可以去掉,然后加速器可以看成5个能量,加速一次消耗5个能量,最多有14格能量,所以2.3维也可以合并,懒得合并了。。递推公式看代码,很容易理解,想想就明白了。

最重要的一点:循环输入,循环输入,循环输入。否则会WA,别问我怎么知道的。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf 1000000000
int a[110],b[110],dp[10010][5][10];
int main()
{
    int L,N,ans=inf;

    while(scanf("%d%d",&L,&N)!=EOF){
        ans=inf;
    memset(dp,0,sizeof(dp));
    for(int i=1; i<5; i++) dp[0][0][i]=inf;
    for(int i=0; i<5; i++)
    {
        dp[0][1][i]=inf;
        dp[0][2][i]=inf;
    }
    for(int i=1; i<=L; i++) scanf("%d",&a[i]);
    for(int i=1; i<=L; i++) scanf("%d",&b[i]);
    for(int ii=0; ii<N; ii++)
    {
        for(int jj=1; jj<=L; jj++)
        {
            //   printf("%d  ",jj);
            for(int j=0; j<5; j++)
            {
                if(j==0)
                {
                    dp[ii*L+jj][0][j]=(dp[ii*L+jj-1][1][0]+b[jj]);
                }
                else
                {
                    dp[ii*L+jj][0][j]=min(dp[ii*L+jj-1][0][j-1]+a[jj],dp[ii*L+jj-1][1][j]+b[jj]);
                }
                if(j==0)             dp[ii*L+jj][1][j]=min(dp[ii*L+jj-1][0][4]+a[jj],dp[ii*L+jj-1][2][j]+b[jj]);
                else         dp[ii*L+jj][1][j]=min(dp[ii*L+jj-1][1][j-1]+a[jj],dp[ii*L+jj-1][2][j]+b[jj]);

                if(j==0)  dp[ii*L+jj][2][j]=min(dp[ii*L+jj-1][1][4]+a[jj],dp[ii*L+jj-1][2][4]+a[jj]);
                else dp[ii*L+jj][2][j]=(dp[ii*L+jj-1][2][j-1]+a[jj]);
                //       printf("%d    %d    %d   \n",dp[ii*L+jj][0][j],dp[ii*L+jj][1][j],dp[ii*L+jj][2][j]);
            }
            //   printf("\n");
        }
    }
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<5; j++)
        {
            ans=min(ans,dp[L*N][i][j]);
        }
    }
    printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值