88分,应该是讨论区里面说的“根据已经申请的结果继续申请”的错误(答案偏小)。我的状态是设f[i][j][0/1][0/1]表示从第i个到第n个(倒叙DP),申请j个课程,第i个是(1)否(0)申请,如果申请位于的教室。这里确实假设了到底位于哪一个教室,但只是为了方便更新路程,在后面的转移中乘上了概率了的。转移方程见下
f[i][j][0][0](没有申请)=
min{(dis[c[i]][c[i+1]]+f[i+1][j][1][0])∗(1−k[i+1])+(dis[c[i]][d[i+1]]+f[i+1][j][1][1])∗k[i+1]dis[c[i]][c[i+1]]+f[i+1][j][0][0]
即分类讨论下一个是否申请了。剩余两个方程的转移同理,我将代码贴上来也许是代码的锅,各位麻烦神仙看一下,谢谢。开始的那个问题,如果我是根据申请结果继续申请,那我不就应该将上面那个转移方程的下面那个方程分成两个写么?因为我已经知道了申请结果了。所以应该不是吧。。也可能是我理解有问题,麻烦神仙指出。
memset(f,0x7f,sizeof(f));
f[n][0][0][0]=f[n][1][1][0]=f[n][1][1][1]=0;
for(int i=n-1;i>=1;i--)
for(int j=0;j<=min(m,n-i+1);j++)
{
f[i][j][0][0]=min(dis[c[i]][c[i+1]]+f[i+1][j][0][0],(dis[c[i]][c[i+1]]+f[i+1][j][1][0])*(1-k[i+1])+(dis[c[i]][d[i+1]]+f[i+1][j][1][1])*k[i+1]);
if(j==0) continue;
f[i][j][1][0]=min(dis[c[i]][c[i+1]]+f[i+1][j-1][0][0],(dis[c[i]][c[i+1]]+f[i+1][j-1][1][0])*(1-k[i+1])+(dis[c[i]][d[i+1]]+f[i+1][j-1][1][1])*k[i+1]);
f[i][j][1][1]=min(dis[d[i]][c[i+1]]+f[i+1][j-1][0][0],(dis[d[i]][c[i+1]]+f[i+1][j-1][1][0])*(1-k[i+1])+(dis[d[i]][d[i+1]]+f[i+1][j-1][1][1])*k[i+1]);
}