G - 跑跑卡丁车 HDU - 1494
DP;
*可以用dp[i]表示在第i段的最小时间,可以用j表示能量槽的个数,最多15个状态
*dp[i][j]:在第i段时的第j个能量槽满的状态下的最小时间,可以肯定最先时间为
*dp[n][k]:n表示圈数,k=[1,14],到达15段的时候会自动清零,也不会得到能量
*dp[i][j]=min(dp[i][j],dp[i-1][j-1]+a[i],dp[i-1][j+5]+b[i])
*注释:dp[i][j]可以通过dp[i-1][j-1]不使用加速卡直接行使得到,
- :dp[i][j]可以通过使用加速卡直接行使得到,使用加速了会减少5个能量槽,
-
相当于用了以后的5个能量槽,dp时候不应该一直纠结时间的状态,超前或延后
- 特别,在j==10的时候可以通过dp[i-1][14]得到,因为此时已经2个加速卡,当集满
- 五个能量槽的时候只是会清零
对于n圈可以表示成nl段
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define N 205
int a[N][2],dp[20005][20];
int n,m;
int main()
{
int i,j,k;
while(~scanf("%d%d",&n,&m))
{
for(i=0;i<n;i++)
scanf("%d",&a[i][1]);
for(i=0;i<n;i++)
scanf("%d",&a[i][2]);
int total=m*n;
memset(dp,999999,sizeof(dp));
dp[1][1]=a[0][1];
for(i=1;i<total;i++)
{
for(j=0;j<15;j++)
{
int op=j+1;
if(op==15) op=10;
dp[i+1][op]=min(dp[i+1][op],dp[i][j]+a[i%n][1]);
if(j>=5)
dp[i+1][j-5]=min(dp[i+1][j-5],dp[i][j]+a[i%n][2]);
}
}
int ans=999999;
for(j=0;j<15;j++)
ans=min(ans,dp[total][j]);
printf("%d\n",ans);
}
return 0;
}
题先不补了,先把博客多写几篇,再补写不了了