uva103(最长递增序列,dag上的最长路)
2015-04-03 21:14
489 查看
题目的意思是给定k个盒子,每个盒子的维度有n dimension
问最多有多少个盒子能够依次嵌套
但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2...en) 只要盒子D的任意全排列,小于盒子E,那么就说明
盒子D能放入盒子E中,其实就是将两个盒子的维度排序,如果前一个盒子的维度依次小于后一个盒子,那么就说明前一个盒子能放入后一个盒子中
这个题目能够转化为最长递增子序列。
首先将盒子的维度从小到大排序,然后将k个盒子,按照排序后的第一维度从小到大排序
这样中的目的是,后面的盒子一定放不到前面的盒子里面,这样是为了消除无后效性。
如果不排序,那么将有后效性,比如第一个盒子不选,但是第二个盒子可以放到第一个盒子里面。
然后就转化为最长递增序列的问题了。
View Code
问最多有多少个盒子能够依次嵌套
但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2...en) 只要盒子D的任意全排列,小于盒子E,那么就说明
盒子D能放入盒子E中,其实就是将两个盒子的维度排序,如果前一个盒子的维度依次小于后一个盒子,那么就说明前一个盒子能放入后一个盒子中
这个题目能够转化为最长递增子序列。
首先将盒子的维度从小到大排序,然后将k个盒子,按照排序后的第一维度从小到大排序
这样中的目的是,后面的盒子一定放不到前面的盒子里面,这样是为了消除无后效性。
如果不排序,那么将有后效性,比如第一个盒子不选,但是第二个盒子可以放到第一个盒子里面。
然后就转化为最长递增序列的问题了。
/* 建图(dag图), 拓扑排序 dp */ #include <stdio.h> #include <string.h> #include <algorithm> #include <stack> using namespace std; const int INF = 1<<30; struct node { int dimension[10]; }a[33]; bool canInput[33][33];//canInput[i][j]判断i能不能放到j里面去 int dp[100]; int path[33]; int ans[100]; int in[30]; int sequeue[30]; int main() { int n,k,i,j,z; while(scanf("%d%d",&k,&n)!=EOF) { memset(ans,0,sizeof(ans)); memset(canInput,false,sizeof(canInput)); memset(dp,0,sizeof(dp)); memset(in,0,sizeof(in)); for(i=0; i<k; ++i) { dp[i] = 1; path[i] = i; for(j=0; j<n; ++j) { scanf("%d",&a[i].dimension[j]); } sort(a[i].dimension,a[i].dimension+n); } for(i=0; i<k; ++i)//预处理,建图 for(j=i+1; j<k; ++j) { bool can = true; for(z=0; z<n; ++z) { if(a[i].dimension[z] >= a[j].dimension[z]) can = false; } if(can) canInput[i][j] = true; can = true; for(z=0; z<n; ++z) { if(a[i].dimension[z] <= a[j].dimension[z]) can = false; } if(can) canInput[j][i] = true; } //每个结点的入度 for(i=0; i<k; ++i) { for(j=0; j<k; ++j) if(canInput[i][j]) in[j]++; } //拓扑排序,sequeue数组存在排序之后的序列 for(i=0; i<k; ++i) { for(j=0; in[j]&&j<k; ++j) NULL; in[j] = -1; sequeue[i] = j; for(z=0; z<k; ++z) if(canInput[j][z]) in[z]--; } //对拓扑排序之后的序列进行最长递增子序列的dp for(i=0; i<k; ++i) for(j=0; j<i; ++j) { if(canInput[sequeue[j]][sequeue[i]] && dp[j]+1>dp[i])//sequeue[i] { dp[i] = dp[j]+1; path[i] = j; } } int cnt = 0,index; for(i=0; i<k; ++i) if(cnt < dp[i]) { cnt = dp[i]; index = i; } printf("%d\n",cnt); ans[--cnt] = index; while(path[index] != index) { ans[--cnt] = path[index]; index = path[index]; } //sequeue[i] printf("%d",sequeue[ans[cnt++]]+1); while(ans[cnt]!=0) { printf(" %d",sequeue[ans[cnt++]]+1); } puts(""); } return 0; }
View Code
相关文章推荐
- UVa 10285 最长的滑雪路径(DAG上的最长路)
- UVA 497 Strategic Defense Initiative【最长严格递增子序列长度及打印】
- UVA 437 The Tower of Babylon (dp + DAG最长序列)
- UVA 103 Stacking Boxes(DAG 上的最长路及其字典序输出)
- uva 103 (DAG矩形嵌套最长路)
- [ACM_动态规划] UVA 12511 Virus [最长公共递增子序列 LCIS 动态规划]
- UVA 103 Stacking Boxes (dp + DAG上的最长路径 + 记忆化搜索)
- UVA - 10534 Wavio Sequence 最长递增子序列的nlogn算法
- UVa 111 - History Grading 最长递增子序列 LIS
- UVa 103 Stacking Boxes 堆砌盒子(DP 最长条件子序列)
- UVa 10534 Wavio Sequence (最长递增子序列 DP 二分)
- UVa 111 - History Grading 最长递增子序列 LIS
- 【动态规划】最长递增子序列代码(UVA 10131)
- uva10534(最长递增子序列的算法变形 复杂度较低)
- UVA 103 Stacking Boxes(最长增长子序列变形)
- UVA10534:Wavio Sequence(最长递增和递减序列 n*logn)(LIS)好题
- UVA103动态规划之DAG上的最长路及其字典序
- UVa 10534 Wavio Sequence ( DP 二分 最长递增子序列 )
- UVa 10534 Wavio Sequence (最长递增子序列 DP 二分)
- UVA 103 Stacking Boxes (dp + DAG上的最长路径 + 记忆化搜索)