【前言】
比较难的题目。
【暴力】
每次搜索最佳路径。
复杂度很大。
【正解】
正难则反。
把问题变成,牛牛要按顺序出村子,尽量不经过有其他牛牛的位置。
考虑一个优美一点的暴力,假设我们知道当前每个点出发离开网格时的最小内疚值,一个牛牛出村子可能会影响一些牛牛的答案,我们就暴力地更新,这样做最坏情况看起来是O(n^4)的,因为假设每个点都会影响很多点,似乎是会达到上界的。
但我们再将牛牛出村子带来的影响量化,很直观的,只会使一部分其他牛牛出村子的答案-1,对于不改变答案的点,它及其它可能延伸的后继都是没必要去遍历的,所以最终复杂度应该是和最初始情况下牛牛们的答案的和有关,大概O(n^3),可能还很不满,足以通过500的数据。
参考代码:
class Solution { public: /** * * @param n int整型 * @param m int整型 * @param c int整型二维数组 * @param cRowLen int c数组行数 * @param cColLen int* c数组列数 * @return int整型 */int nn,mm; int fl[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int a[300000],b[300000],f[1000][1000]; void dfs(int x,int y) { for (int i=0;i<=3;i++) { int xx=x+fl[i][0],yy=y+fl[i][1]; if (xx>0&&xx<=nn&&yy>0&&yy<=mm&&f[xx][yy]>f[x][y]) { f[xx][yy]=f[x][y]; dfs(xx,yy); } } } int wwork(int n, int m, int** c, int cRowLen, int* cColLen) { // write code here nn=n;mm=m; for (int i=0;i<n*m;i++) { a[n*m-i]=c[i][0]; b[n*m-i]=c[i][1]; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) f[i][j]=min(min(i-1,n-i),min(j-1,m-j)); int ans=0; for (int i=1;i<=n*m;i++) { ans=ans+f[a[i]][b[i]]; dfs(a[i],b[i]); } return ans; } };