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;
}
DAG 模型