自己用优化了空间的O(NC)算法写,WA是因为格式和long long。以后要仔细看输出那一栏的全部输出细节,以及输入那一栏的数据范围。
还好C才100,所以没有超时。
但是大白书上的方法却优化到了O(N),也就是C很大也能过,十分优秀。
先将自己的O(NC)算法。
dp[i][j]表示捡完第i个垃圾后剩余j空间的最短路程。如果是-1说明没有此状态。
那么状态转移方程:
dp[i][j]=dp[i-1][j+w[i]]+dist(i,i-1) 其中j+w[i]<C且dp[i-1][j+w[i]]!=-1
意思是捡完第i-1个垃圾不回家继续捡第i个垃圾不回家的最短路程。直接计算。
特别的,也就是当j+w[i]==C时 dp[i][C-w[i]]=dp[i-1][C]+dist(0,i)
意思是捡完第i-1个垃圾回家继续捡第i个垃圾不回家的最短路程。直接计算。
还有一个情况要更新 令MIN=min(dp[i][j]+dist(0,i)) 0<=j<C
dp[i][C]=min(dp[i-1][C]+2*dist(0,i),MIN)。
意思是要计算捡完第i个垃圾后回家的最短路程,可以捡完第i-1个垃圾回家再来捡第i个垃圾再回家,也可以直到捡完第i个垃圾再回家。这里取最小值。
如果无法转移就赋值为-1。
发现新状态总是由空间更多的旧状态转移过来,就像01背包那样,因此可以优化空间,从小往大遍历。细节参考代码。
再讲讲大白书上的代码。
定义dp[i]为捡完第i个垃圾回家后的最短路程。枚举上一次回家的时候j,显然这是一个连续的值。dp[i]