1. 程式人生 > 其它 >1575. 統計所有可行路徑leetcode (dfs+記憶化搜尋 轉 dp)

1575. 統計所有可行路徑leetcode (dfs+記憶化搜尋 轉 dp)

題目連結

這個題,先來一個裸dfs看看能騙幾分:

class Solution {
public:
    long long num=0;
    void dfs(vector<int>& locations, int start,int pre, int finish, int fuel ){
        if(fuel < 0){
            return ;
        }
        if(start==finish){
            num++;
            num=num%(1000000007);
            return ;
        }
        int len=locations.size();
        for (int i = 0; i < len; ++i) {
            if(i!=start){
                dfs(locations,i,start,finish,fuel-abs(locations[i] - locations[start]));
            }

        }
    }
    int countRoutes(vector<int>& locations, int start, int finish, int fuel) {
        dfs( locations,  start, -1, finish,  fuel);
        return num;
    }
};

誒呀呀,怎麼才過了三個測試樣例。,,

其實想想也是,如果fuel一多,這不就直接爆炸,跑過來跑過去的,飄了~~~~

那再考慮一下的話就是,當油量和所在位置一樣的時候,其實路徑是一樣的,我們可以記錄一下的嘛(dfs+記憶化搜尋)

注意一個點,就是它就算到了終點也只是把結果+1而已,根本不需要return

class Solution {
public:
    int num=0;
    vector<int> lujing;
    int mem[250][250];
    int dfs(vector<int>& locations, int now, int finish, int fuel ){
        if(fuel < 0){
            return 0;
        }
        if(mem[now][fuel]!=-1){
            return mem[now][fuel];
        }
        mem[now][fuel]=0;
        if(now==finish){
            mem[now][fuel]+=1;
            mem[now][fuel]%=1000000007;

        }
        int len=locations.size();
        for (int i = 0; i < len; ++i) {
            int diff=abs(locations[i] - locations[now]);
            if(i!=now && diff<=fuel){
                mem[now][fuel]+=dfs(locations,i,finish,fuel-abs(locations[i] - locations[now]));
                mem[now][fuel]%=1000000007;

            }

        }
        return mem[now][fuel];
    }
    int countRoutes(vector<int>& locations, int start, int finish, int fuel) {
        memset(mem,-1,sizeof(mem));
        return dfs( locations,  start,  finish,  fuel);
    }
};

昂,其實這樣就過了

但是!!!據說記憶化搜尋都可以變成dp,那為什麼不,,,問一下神奇海螺呢?

其實這個時候我們的dp陣列都已經出來了。就是剛剛dfs的時候用的那個陣列,現在我們要做的是,根據dfs程式碼把他變成一個dp的解法。

第一維沒有明確的大小關係,但是第二維油量,要求大油量依賴小油量,所以這一維應該是從低列舉的。

class Solution {
public:
    int countRoutes(vector<int>& locations, int start, int finish, int fuel) {
        int mem[250][250]={0};
        int len=locations.size();
        memset(mem,-1,sizeof(mem));
        for (int i = 0; i <= fuel ; ++i) {
            mem[finish][i]=1;//這個是邊界條件

        }
        for (int i = 0; i <= fuel ; ++i) {
            for (int j = 0; j < len; ++j) {
                for (int k = 0; k < len; ++k) {
                    if(j!=k) {
                        int need = abs(locations[j]-locations[k]);
                        if(i>=need){
                            mem[k][i]+=mem[j][i-need];//注意這個地方,mem[k]才是你要更新的
                            mem[k][i]%=1000000007;
                        }
                    }

                }

            }

        }
        return mem[start][fuel];

    }
};
為了自己,和那些愛你的人