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; }
3.n-queue
http://www.cnblogs.com/yanlingyin/archive/2011/12/19/2292041.html