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;
}

DAG 模型

时间: 2024-10-12 09:14:18

DAG 模型的相关文章

UVA103 dp基础题,DAG模型

1.UVA103 嵌套n维空间 DAG模型记忆化搜索,或者 最长上升子序列. 2.dp[i]=max( dp[j]+1),(第i个小于第j个) (1) //DAG模型记忆化搜索 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define F

NYOJ16|嵌套矩形|DP|DAG模型|记忆化搜索

矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中.你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内. 输入 第一行是一个正正数N(0<N<10),表示测试数据组数,每组测

DAG模型:嵌套矩形

有n个矩形,每个矩形可以用两个整数a,b描述,表示它的长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当 a<c,b<d,或者b<c,a<d(相当于把矩形X旋转90°).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在 (3,4)内.你的任务是选出尽可能多的矩形排成一行.使得除了最后一个之外,每个矩形都可以嵌套在下一个矩形内. 分析: 矩形之间的"可嵌套"关系是一个典型的二元关系,二元关系可以用图来建模.如果矩形X可以嵌套在矩形Y里,我们就从X到Y连

DAG模型

数字三角形: 1.递归计算 int solve(int i,int j) { return a[i][j] +(i==n?0:max(solve(i+1,j),solve(i+1,j+1))); } 2.记忆化搜索,不用指明计算顺序,并且保证每个状态只计算一次 int solve(int i,int j) { if(d[i][j]>=0) return d[i][j]; return d[i][j] = a[i][j] +(i==n?0:max(solve(i+1,j),solve(i+1,j+

DAG模型(矩形嵌套)

推荐在线例题:http://acm.nyist.net/JudgeOnline/problem.php?pid=16 题摘: 矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中.你的任务是选出尽可能多的矩形排成一行,使得除最后

DP入门(2)——DAG上的动态规划

有向无环图(DAG,Directed Acyclic Graph)上的动态规划是学习动态规划的基础.很多问题都可以转化为DAG上的最长路.最短路或路径计数问题. 一.DAG模型 [嵌套矩形问题] 问题:有n个矩形,每个矩形可以用两个整数a.b描述,表示它的长和宽.矩形X(a , b)可以嵌套在矩形Y(c , d)中当且仅当a<c,b<d,或者b<c,a<d(相当于把矩形X旋转90°).例如(1,5)可以嵌套在(6, 2)内,但不能嵌套在(3, 4)内.你的任务是选出尽可能多的矩形排

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H. Skiing

题意:在这个寒假中,鲍勃有计划在山区度假胜地滑雪.这个滑雪胜地有M个不同的滑雪道和N个不同的标志位于那些转弯处点.从第S标记到第T标志的第i路径具有长度L.每个路径必须遵循降低高度的原则,起点必须严格高于终点. 现在,你应该帮助鲍勃找到最长的滑雪道. 思路:因为说起点必须严格高于终点,所以是一个有向图,而且不可能存在环,可以看作是一个DAG模型, 求DAG上的最长路可以用dp来求,有些时候也可以看作AOE网,这样就可以用拓扑排序来求关键路径来解决了: 代码: #include<algorithm

hdu 1078 FatMouse and Cheese

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5701    Accepted Submission(s): 2320 Problem Description FatMouse has stored some cheese in a city. The city can be considered as a square grid of

uva437 poj2241 The Tower of Babylon dp

// 这题开始在算法竞赛入门经典的书上状态表示 // dp[i][j]表示前i个方块以第j条边为高所能得到的最大高度值 // dp[i][j] = max(dp[0...i-1][0,1,2]+block[i][j]); // 就是一个DAG模型 // 这样记忆化搜索就行啦,还是有些技巧的 // // 第二种做法就是递推 // 首先把一个方块变为6个,即表示长,宽,高 // 当然,首先得要把底面积从大到小排序 // dp[i]表示前i种方块所能达到的最大高度 // dp[i] = max(dp[