题目的意思是给定k个盒子,每个盒子的维度有n dimension

问最多有多少个盒子能够依次嵌套

但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2...en) 只要盒子D的任意全排列,小于盒子E,那么就说明

盒子D能放入盒子E中,其实就是将两个盒子的维度排序,如果前一个盒子的维度依次小于后一个盒子,那么就说明前一个盒子能放入后一个盒子中

这个题目能够转化为最长递增子序列。

首先将盒子的维度从小到大排序,然后将k个盒子,按照排序后的第一维度从小到大排序

这样中的目的是,后面的盒子一定放不到前面的盒子里面,这样是为了消除无后效性。

如果不排序,那么将有后效性,比如第一个盒子不选,但是第二个盒子可以放到第一个盒子里面。

然后就转化为最长递增序列的问题了。

 /*
感觉像是变形的最长递增子序列
如何快捷的判断一个盒子进过变换能放到另一个盒子里面呢?
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int INF = <<;
struct node
{
int minNum;
int id;
int dimension[];
bool operator<(const node&rhs)const
{
return minNum < rhs.minNum;
}
}a[];
bool canInput[][];//canInput[i][j]判断j能不能放到i里面去
int dp[];
int path[];
int ans[];
int main()
{ int n,k,i,j,z;
while(scanf("%d%d",&k,&n)!=EOF)
{
memset(ans,,sizeof(ans));
memset(canInput,false,sizeof(canInput));
memset(dp,,sizeof(dp));
for(i=; i<k; ++i)
{
dp[i] = ;
path[i] = i;
a[i].minNum = INF;
a[i].id = i+;
for(j=; j<n; ++j)
{
scanf("%d",&a[i].dimension[j]);
a[i].minNum = min(a[i].minNum,a[i].dimension[j]);
}
sort(a[i].dimension,a[i].dimension+n);
} sort(a,a+k);
for(i=; i<k; ++i)//预处理,判断i能不能放到j里面去
for(j=i+; j<k; ++j)
{
bool can = true;
for(z=; z<n; ++z)
{
if(a[i].dimension[z] >= a[j].dimension[z])
can = false;
}
if(can)
canInput[j][i] = true;
}
//这里就是求最长递增子序列,时间复杂度是O(k*k)
for(i=; i<k; ++i)
for(j=; j<i; ++j)
{
if(canInput[i][j])//预处理之后,就变成了一维的最长递增子序列的求解了
{
if(dp[j]+ >dp[i])
{
dp[i] = dp[j]+;
path[i] = j;
//break; 这里可不能break, 比如例子:1 2 3 4 5 11 12 13 10 14
}
}
}
int cnt = ,index;
for(i=; i<k; ++i)
if(cnt < dp[i])
{
cnt = dp[i];
index = i;
} printf("%d\n",cnt);
ans[--cnt] = a[index].id; while(path[index]!=index)
{
ans[--cnt] = a[path[index]].id;
index = path[index];
}
printf("%d",ans[cnt++]);
while(ans[cnt]!=)
{
printf(" %d",ans[cnt++]);
}
puts("");
}
return ;
}

当然也可以建图(dag图),然后求最长路, 最长路的一种求法就是进行拓扑排序,然后进行最长递增子序列dp,  拓扑排序同上面的排序一样,也是为了消除后效性

然后这种做法,相当于上面,太复杂了。 但是是为了天马行空的想法而A题,而不是为了A题而A题。

 /*
建图(dag图),
拓扑排序
dp
*/ #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
using namespace std;
const int INF = <<;
struct node
{
int dimension[]; }a[];
bool canInput[][];//canInput[i][j]判断i能不能放到j里面去
int dp[];
int path[];
int ans[];
int in[];
int sequeue[];
int main()
{
int n,k,i,j,z;
while(scanf("%d%d",&k,&n)!=EOF)
{
memset(ans,,sizeof(ans));
memset(canInput,false,sizeof(canInput));
memset(dp,,sizeof(dp));
memset(in,,sizeof(in));
for(i=; i<k; ++i)
{
dp[i] = ;
path[i] = i;
for(j=; j<n; ++j)
{
scanf("%d",&a[i].dimension[j]);
}
sort(a[i].dimension,a[i].dimension+n);
} for(i=; i<k; ++i)//预处理,建图
for(j=i+; j<k; ++j)
{
bool can = true;
for(z=; z<n; ++z)
{
if(a[i].dimension[z] >= a[j].dimension[z])
can = false;
}
if(can)
canInput[i][j] = true;
can = true;
for(z=; z<n; ++z)
{
if(a[i].dimension[z] <= a[j].dimension[z])
can = false;
}
if(can)
canInput[j][i] = true; }
//每个结点的入度
for(i=; i<k; ++i)
{
for(j=; j<k; ++j)
if(canInput[i][j])
in[j]++;
}
//拓扑排序,sequeue数组存在排序之后的序列
for(i=; i<k; ++i)
{
for(j=; in[j]&&j<k; ++j)
NULL;
in[j] = -;
sequeue[i] = j;
for(z=; z<k; ++z)
if(canInput[j][z])
in[z]--;
} //对拓扑排序之后的序列进行最长递增子序列的dp
for(i=; i<k; ++i)
for(j=; j<i; ++j)
{
if(canInput[sequeue[j]][sequeue[i]] && dp[j]+>dp[i])//sequeue[i]
{
dp[i] = dp[j]+;
path[i] = j;
}
}
int cnt = ,index;
for(i=; 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++]]+);
while(ans[cnt]!=)
{
printf(" %d",sequeue[ans[cnt++]]+);
}
puts("");
}
return ;
}

uva103(最长递增序列,dag上的最长路)的更多相关文章

  1. [LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  2. [LeetCode] 673. Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  3. POJ 2533 Longest Ordered Subsequence 最长递增序列

      Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequenc ...

  4. NYOJ_矩形嵌套(DAG上的最长路 + 经典dp)

    本题大意:给定多个矩形的长和宽,让你判断最多能有几个矩形可以嵌套在一起,嵌套的条件为长和宽分别都小于另一个矩形的长和宽. 本题思路:其实这道题和之前做过的一道模版题数字三角形很相似,大体思路都一致,这 ...

  5. UVa 10285 最长的滑雪路径(DAG上的最长路)

    https://vjudge.net/problem/UVA-10285 题意: 在一个R*C的整数矩阵上找一条高度严格递减的最长路.起点任意,但每次只能沿着上下左右4个方向之一走一格,并且不能走出矩 ...

  6. Leetcode 674.最长递增序列

    最长递增序列 给定一个未经排序的整数数组,找到最长且连续的的递增序列. 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3. 尽管 [1,3 ...

  7. XHXJ's LIS HDU - 4352 最长递增序列&数位dp

    代码+题解: 1 //题意: 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k 3 //注意是最长序列,可不是子串.子序列是不用紧挨着的 4 // 5 // ...

  8. LIS(最长的序列)和LCS(最长公共子)总结

    LIS(最长递增子序列)和LCS(最长公共子序列)的总结 最长公共子序列(LCS):O(n^2) 两个for循环让两个字符串按位的匹配:i in range(1, len1) j in range(1 ...

  9. Vulnerable Kerbals CodeForces - 772C【拓展欧几里得建图+DAG上求最长路】

    根据拓展欧几里得对于同余方程 $ax+by=c$ ,有解的条件是 $(a,b)|c$. 那么对于构造的序列的数,前一个数 $a$  和后一个数 $b$ ,应该满足 $a*x=b(mod m)$ 即 $ ...

随机推荐

  1. c++/c/java 资源共享群

    Hi,我邀请你加入360云盘文件共享群:c++&c&java, 打开邀请链接:http://qun.yunpan.360.cn/10005202 , 输入邀请码:1357

  2. 移植一个开源点餐网到SAE平台上

    记得以前我准备弄个点餐网的,但是由于一些原因没有做下去. 前几天将网上的一个点餐源码移植到了SAE上,网址http://diancan4sae.sinaapp.com. 我想做个外卖网,先选一个学校周 ...

  3. drupal进入不了后台时候的解决办法,作者使用drush方案,已验证

    drupal把正在用的主题不小心删了,怎么进后台? 方法一: 去variable表里把默认主题换了 方法二: ?q=user 登录到管理区,开启简洁连接使用user(网站根目录下面) admin/ap ...

  4. 一个计算器的C语言实现

    今天在读<编译原理及实践>时.看到了一个简单的整数计算器的实现. 依照书上的思路,我略微进行了扩展: 1.从整数计算器扩展到小数计算器. 2.支持除法 3.支持空字符. 执行效果例如以下: ...

  5. [Android学习笔记]PopupWindow的使用

    什么时候使用PopupWindow? 当业务需求的交互形式需要在当前页弹出一个简单可选项UI与用户进行交互时,可使用PopupWindow完成此功能开发 Android Dev API Doc Pop ...

  6. 【Windows Phone设计与用户体验】关于移动产品的Loading用户体验的思考

    作为一款运行在移动端上的产品,必定会有一些耗时的操作.为了具有良好的用户体验,Loading效果是必不可少的,而什么形式的Loading才会有良好的用户体验? Loading形式简单分为两类: 一.遮 ...

  7. 对于stackoverflow的中文翻译的相关问题

    我们非常多朋友都给我留言说.希望我翻译一下stackoverflow的问题以及答案,首先我也非常愿意为大家翻译,在能够帮助大家的同一时候,对我本人的技能的提升有优点:可是工作量实在太大,所以我不可能翻 ...

  8. ORACLE数据库常见问题汇总

    提交事务的时候提示(数据库被一个用户锁住的解决方法) select object_id,session_id,locked_mode from v$locked_object; select t2.u ...

  9. python基础教程_学习笔记10:异常

    异常 什么是异常 Python用异常对象来表示异常情况.遇到错误后,会引发异常.假设异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止运行: >>> ...

  10. 【C语言】写一个函数,实现字符串内单词逆序

    //写一个函数,实现字符串内单词逆序 //比如student a am i.逆序后i am a student. #include <stdio.h> #include <strin ...