1. 程式人生 > 程式設計 >windows java.exe記憶體暴漲解決、idea跑java\ tomcat記憶體無限增長

windows java.exe記憶體暴漲解決、idea跑java\ tomcat記憶體無限增長

既然是工作之間的相互關係,那麼一定是有向無環圖,所以可以用記憶化來做

狀態定義:\(f[i]\)表示從\(i\)號工作開始完成後續所有工作的安排方法集合,儲存能夠完成\(i\)號及其後續所有工作所需的最短時間

狀態轉移:\(f[i] = w[i] + max\{f[j_1], f[j_2],...f[j_k],...\},\)其中\(i\)\(j_k\)的直接準備工作(即DAG上存在\(i\to j_k\)的邊)

初始條件:對於沒有後續的結點\(k\)\(f[k] = w[k]\)

答案:\(max\{f[i]\},i\)為所有的無前驅的結點

鄰接表存圖複雜度:\(O(N + E)\)

#include<iostream>
#include<cstring>

using namespace std;

const int N = 10010, M = 1000010;

int h[N], e[M], ne[M], idx;
int w[N], in[N], f[N];
int n;

void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int dfs(int u){
    if(f[u]) return f[u];
    
    f[u] = w[u];
    
    for(int i = h[u]; i != -1; i = ne[i]){
        int j = e[i];
        f[u] = max(f[u], w[u] + dfs(j));
    }
    
    return f[u];
}

int main(){
    memset(h, -1, sizeof h);
    
    cin >> n;
    
    for(int i = 1; i <= n; i ++){
        int num, len;
        cin >> num >> len;
        
        w[num] = len;
        
        int pre;
        while(cin >> pre, pre) add(pre, num), in[num] ++;
    }
    
    int res = 0;
    
    for(int i = 1; i <= n; i ++)
        if(in[i] == 0)
            res = max(res, dfs(i));
            
    cout << res << endl;
    
    return 0;
}