* Computer Science/Algorithm

baekjun 11066. 파일 합치기

soicem 2018. 8. 14. 07:39

 knuth's optimization을 공부해야함


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <algorithm>
 
#define MAX    0x12345678
 
using namespace std;
int files[501];
int dp[501][501];
int pSum[501];
int n;
 
// iteration
// dp[i][j] = min(dp[i][j], dp[i][mid] + dp[mid + 1][j] + pSum[j] - pSum[i - 1]); (i<=k<j)
void combineFile() {
    for (int d = 1; d < n; d++) {
        for (int tx = 1; tx + d <= n; tx++) {
            int ty = tx + d; // ty <= n
            dp[tx][ty] = MAX;
            for (int mid = tx; mid < ty; mid++) {
                dp[tx][ty] = min(dp[tx][ty], dp[tx][mid] + dp[mid + 1][ty] + pSum[ty] - pSum[tx - 1]);
            }
        }
    }
}
 
int combineFile2(int tx, int ty) {
    if (dp[tx][ty] != MAX) {
        return dp[tx][ty];
    }
    if (tx == ty) {
        return dp[tx][ty] = 0;
    }
    if (tx + 1 == ty) {
        return dp[tx][ty] = files[tx] + files[ty];
    }
    for (int mid = tx; mid < ty; mid++) {
        int left = combineFile2(tx, mid);
        int right = combineFile2(mid + 1, ty);
        dp[tx][ty] = min(dp[tx][ty], left + right);
    }
    return dp[tx][ty] += pSum[ty] - pSum[tx - 1];
}
 
int main() {
    int cases;
    cin >> cases;
    while (cases--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> files[i];
            pSum[i] = pSum[i - 1+ files[i];
        }
        // combineFile();
 
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                dp[i][j] = MAX;
            }
        }
        cout << combineFile2(1, n) << endl;
    }
    //system("pause");
    return 0;
}
cs


18 nov 2


D[i][j] = D[i][k] + D[k+1][j] + pSum[j] - pSum[i] (i <= k < j)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <cstring>
using namespace std;
 
int files[501];
int cache[501][501];
int pSum[501];
 
int fc(int i, int j){
    if(i == j){
        return 0;
    }
    if(cache[i][j]!= -1){
        return cache[i][j];
    }
    int & ret = cache[i][j];
    for(int k = i; k < j; k++){
        int tmp = fc(i, k) + fc(k + 1, j) + pSum[j] - pSum[i-1];
        if(ret == -1 || ret > tmp){
            ret = tmp;
        }
    }
    return ret;
}
 
int main(){
    int cases;
    cin >> cases;
    while(cases--){
        int N;
        cin >> N;
        memset(cache, -1sizeof(cache));
        memset(pSum, 0sizeof(pSum));
        for(int i = 1; i <= N; i++){
            cin >> files[i];
            pSum[i] = pSum[i - 1+ files[i];
        }
        cout << fc(1, N);
    }
    return 0;
}
 
cs


'* Computer Science > Algorithm' 카테고리의 다른 글

baekjun 9252. LCS2  (0) 2018.08.20
baekjun 9461. 파도반수열  (0) 2018.08.14
baekjun 9251. LCS(Longest Common Sequence)  (0) 2018.08.12
baekjun 1520. 내리막 길  (0) 2018.08.09
baekjun 2156. 포도주 시식  (0) 2018.08.08