看了两天终于看懂了,但是思路还是不太好想
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int dp[255][255],dpp[255][255][3],mk[255];// dp是动态规划数组 dpp[i][j][0]的意思就是在时间i上j站点有没有向左去的列车
int inf=0x3f3f3f3f; // dpp[i][j][1]的意思就是在时间i上j站点有没有向右去的列车 mk存储到下一个站点所要的时间
int casee=0;
int main()
{
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
for(int i=1; i<n; i++)
scanf("%d",&mk[i]);
memset(dpp,0,sizeof(dpp)); //因为dpp数组是找出在某个时间上的某个站点有没有火车,所以初始化
int ta,ca,tb;
scanf("%d",&ta);
while(ta--)
{
scanf("%d",&ca); //在站点起始处,在ca时间发一趟列车
for(int i=1; i<n; i++)
{
if(ca<=m)
dpp[ca][i][0]=1; //标记有列车
ca+=mk[i]; //计算出到下一个站点什么时候有车,最后一个站点不用计算
} //是因为dpp数组存的是这个站点什么时候有向右的的车,最后一个站点没有向右的车,所以不用计算
}
scanf("%d",&tb);
while(tb--)
{
scanf("%d",&ca);
for(int i=n-1; i>=1; i--)
{
if(ca<=m)
dpp[ca][i+1][1]=1;//同理上面的计算过程,至于i+1是因为在上面
ca+=mk[i]; //存储到下一站的时间的时候的问题,现在计算的是向左
} //的,所以在计算这个站点是否有车的时候,计算时的i与存储
} //时的i有差值,所以要+1;
for(int i=1;i<n;i++)
dp[m][i]=inf;
dp[m][n]=0; //
for(int i=m-1;i>=0;i--)// m代表时间
{
for(int j=1;j<=n;j++) // n代表车站数
{
dp[i][j]=dp[i+1][j]+1; //因为间谍只能通过火车移动,所以假如没有列车的话只能在原地等候
if(j<n&&dpp[i][j][0]&&i+mk[j]<=m) //判断还需不需要往右走
dp[i][j]=min(dp[i][j],dp[i+mk[j]][j+1]); //因为时间是在不断减小的,所以为了让等待的时间尽可能的小现在就是有列车就是上,上了列车就代表多加一站
if(j>1&&dpp[i][j][1]&&i+mk[j-1]<=m) //判断向左走
dp[i][j]=min(dp[i][j],dp[i+mk[j-1]][j-1]);
}
}
printf("Case Number %d: ",++casee);
if(dp[0][1]>=inf)
printf("impossible\n");
else
printf("%d\n",dp[0][1]);
}
return 0;
}