箱子嵌套
原题链接
箱子嵌套
描述
考虑一个给出为
在这个问题中你将分析许多关于
例如,箱子
输入
第一行有两个整数,第一个整数为箱子的总数K,第二个整数为每个箱子的空间维数N。以下K行,每行表示一个箱子,有N个尺度数据,数据间用一个或数个空格分开。(
仅包含一个整数,输出最大箱子嵌套数目。
输入样例 1
5 2
3 7
8 10
5 2
9 11
21 18
输出样例 1
5
动态规划
完美嵌套
解决这道题,首先要知道如何将两个箱子完美的进行嵌套。
举个例子
a:4 5 4 8
b:5 5 11 9
把a嵌进b箱子。
从大的开始考虑:a[4]是a中的最大值,值为8。
现在有了2种选择:
-
用11
-
用9
11是b中的最大值,9是次大值。
如果用的是9,那么11用去哪里。
如果把a中的其中一个换成10呢?
就不能很好的嵌套了,所以最佳选择为11。
再举个例子:
-
a[i],a[j]
-
b[i],b[j]
把a嵌进b里(这是按照排完序后的顺序)
假设a[j]>b[j],我们就只能用b[i]套住a[j]。 但是明显b[j]<a[i],所以就不行。
这道题目要的是完胜,而不是田忌赛马,有一个不行,就是全部不行。
结论
只要在每个箱子的内部排序就是最佳策略。
排完序,一看,求每一个箱子都下降的最长序列,这不就是最长下降子序列吗?
最长下降子序列需要给数组排序。
给所有的维度排序ing...
其实有一个小特性,就是求最长上升下降子序列,需要有一定的顺序,但是不知道为什么,并不需要按照严格的顺序来排序。
所以根据这个特性,我们直接对每个维度的最大值来排序就好了。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int dp[11111];
struct Node{
int k[11];
}a[11111];
bool cmp(int x,int y) {
return x>y;
}
bool cmp1(Node x,Node y) {
return x.k[1]<y.k[1];
}
bool check(int x,int y) {
for(int i=1;i<=m;i++) {
if(a[x].k[i]<=a[y].k[i]) return false;
}
return true;
}
int main(){
freopen("box.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
cin>>a[i].k[j];
}
sort(a[i].k+1,a[i].k+m+1,cmp);
dp[i]=1;
}
sort(a+1,a+n+1,cmp1);
int ans=0;
for(int i=1;i<=n;i++) {
for(int j=1;j<i;j++) {
if(check(i,j)) {
dp[i]=max(dp[i],dp[j]+1);
}
}
}
for(int i=1;i<=n;i++) {
ans=max(ans,dp[i]);
}
cout<<ans;
return 0;
}
/*
5 2
3 7
8 10
5 2
9 11
21 18
*/
本文作者:cjrqwq
本文链接:https://www.cnblogs.com/yfzqwq/p/18492854
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步