因为是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;
}