首页 > 代码库 > DAG 模型

DAG 模型

1.

#include<stdio.h>
#include<string.h>
#define MAXN 1010
int n, G[MAXN][MAXN];
int x[MAXN], y[MAXN], d[MAXN];

int dp(int i) {
  int& ans = d[i];
  if(ans > 0) return ans;
  ans = 1;
  for(int j = 1; j <= n; j++) if(G[i][j]) ans >?= dp(j)+1;
  return ans;
}

void print_ans(int i) {
  printf("%d ", i);
  for(int j = 1; j <= n; j++) if(G[i][j] && d[i] == d[j]+1) {
    print_ans(j);
    break;
  }
}

int main() {
  int i, j, ans, best;
  scanf("%d", &n);
  for(i = 1; i <= n; i++) {
    scanf("%d%d", &x[i], &y[i]);
    if(x[i] > y[i]) {
      int t = x[i]; x[i] = y[i]; y[i] = t;
    }
  }
  memset(G, 0, sizeof(G));
  for(i = 1; i <= n; i++)
    for(j = 1; j <= n; j++)
      if(x[i] < x[j] && y[i] < y[j]) G[i][j] = 1;

  ans = 0;
  for(i = 1; i <= n; i++)
    if(dp(i) > ans) {
      best = i;
      ans = dp(i);
    }
  printf("%d\n", ans);
  print_ans(best);
  printf("\n");
  return 0;
}

2.

#include<stdio.h>
#include<string.h>
#define MAXN 1010
int n, G[MAXN][MAXN];
int x[MAXN], y[MAXN], d[MAXN];

int dp(int i) {
  int& ans = d[i];
  if(ans > 0) return ans;
  ans = 1;
  for(int j = 1; j <= n; j++) if(G[i][j]) ans >?= dp(j)+1;
  return ans;
}

int path[MAXN];
void print_all(int cur, int i) {
  path[cur] = i;
  if(d[i] == 1) {
    for(int j = 0; j <= cur; j++) printf("%d ", path[j]);
    printf("\n");
  }
  for(int j = 1; j <= n; j++) if(G[i][j] && d[i] == d[j]+1)
    print_all(cur+1, j);
}

int main() {
  int i, j, ans, best;
  scanf("%d", &n);
  for(i = 1; i <= n; i++) {
    scanf("%d%d", &x[i], &y[i]);
    if(x[i] > y[i]) {
      int t = x[i]; x[i] = y[i]; y[i] = t;
    }
  }
  memset(G, 0, sizeof(G));
  for(i = 1; i <= n; i++)
    for(j = 1; j <= n; j++)
      if(x[i] < x[j] && y[i] < y[j]) G[i][j] = 1;

  ans = 0;
  for(i = 1; i <= n; i++) ans >?= dp(i);
  printf("%d\n", ans);

  for(i = 1; i <= n; i++)
    if(ans ==  dp(i)) print_all(0, i);

  return 0;
}

硬币问题(递推)
  coin.cpp(根据指标函数重建方案)
  coin2.cpp(递推时保存最优决策)

1.

#include<stdio.h>
#define MAXN 105
#define INF 1000000000
int V[MAXN], min[MAXN], max[MAXN];
int n, S;

void print_ans(int* d, int S) {
  for(int i = 1; i <= n; i++)
    if(S>=V[i] && d[S]==d[S-V[i]]+1) {
      printf("%d ", i);
      print_ans(d, S-V[i]);
      break;
    }
}

int main() {
  scanf("%d%d", &n, &S);
  for(int i = 1; i <= n; i++) scanf("%d", &V[i]);
  min[0] = max[0] = 0;
  for(int i = 1; i <= S; i++) {
    min[i] = INF;
    max[i] = -INF;
  }
  for(int i = 1; i <= S; i++)
    for(int j = 1; j <= n; j++)
      if(i >= V[j]) {
        min[i] <?= min[i-V[j]] + 1;
        max[i] >?= max[i-V[j]] + 1;
      }
  printf("%d %d\n", min[S], max[S]);
  print_ans(min, S);
  printf("\n");
  print_ans(max, S);
  printf("\n");
  return 0;
}

2.

#include<stdio.h>
#define MAXN 105
#define INF 1000000000
int V[MAXN], min[MAXN], max[MAXN], min_coin[MAXN], max_coin[MAXN];
int n, S;

void print_ans(int* d, int S) {
  while(S) {
    printf("%d ", d[S]);
    S -= V[d[S]];
  }
}

int main() {
  scanf("%d%d", &n, &S);
  for(int i = 1; i <= n; i++) scanf("%d", &V[i]);
  min[0] = max[0] = 0;
  for(int i = 1; i <= S; i++) {
    min[i] = INF;
    max[i] = -INF;
  }
  for(int i = 1; i <= S; i++)
    for(int j = 1; j <= n; j++)
      if(i >= V[j]) {
        if(min[i] > min[i-V[j]] + 1) {
          min[i] = min[i-V[j]] + 1;
          min_coin[i] = j;
        }
        if(max[i] < max[i-V[j]] + 1) {
          max[i] = max[i-V[j]] + 1;
          max_coin[i] = j;
        }
      }
  printf("%d %d\n", min[S], max[S]);
  print_ans(min_coin, S);
  printf("\n");
  print_ans(max_coin, S);
  printf("\n");
  return 0;
}