套娃游戏,给出它们的高度和长度,计算最少能嵌套几组套娃

套娃(dolls)
问题描述:
套娃游戏大家一定玩过,套娃在嵌套放入的时候,每一个套娃只可以嵌入高.
度和长度均比它大
........的套娃内。现在有一批套娃,给出它们的高度和长度,计算最
少能嵌套出几组套娃。
输入格式:
第一行为正整数t(≤5),表示数据组数;每组数据中,第一行为正整数m(≤
30000),表示一共有m只套娃;接下来m行,每行两个正整数wi和hi(wi,hi≤10
5),
分别表示每一只套娃的高度和长度。
输出格式:
对于每组数据,输出最少嵌套的组数。
输入样例2
4
2030
1010
3020
4050
3
1030
2020
3010
2
输出样例

通过链表实现。以下代码没有考虑旋转(也就是w只和w比较,h之和h比较)。
运行结果:

img

代码:

#include <iostream>
using namespace std;

typedef struct _toys
{
    int w;
    int h;
}MyToy;

typedef struct _linknode
{
    MyToy data;
    _linknode* next;
}LinkNode,*List;


//释放内存
void release(List head)
{
    while (head)
    {
        List q = head->next;
        delete head;
        head = q;
    }
}

//判断test是否能插入head
List Judege(List head, List test)
{
    List p = head;
    while (p->next)
    {
        if (test->data.w < p->next->data.w && test->data.h < p->next->data.h) //再前面插入
        {
            return p;
        }
        else if (test->data.w > p->next->data.w && test->data.h > p->next->data.h)
            p = p->next;
        else
            return 0;
    }
    return p;
}


void Deal(List head)
{
    List p = head;
    List allLinks[30001] = { 0 };
    int kk = 0;
    if (head->next == 0)
        cout << "0" << endl;

    while (head->next)
    {
        //将第一个节点从队列中取出
        List q = head->next; 
        head->next = q->next;
        //插入新的队列
        q->next = 0;
        allLinks[kk] = new LinkNode;
        allLinks[kk]->next = q;
        

        //从链表中查找能嵌套该娃娃的其它娃娃
        List scHead = head;
        while (scHead->next)
        {
            //判断scHead->next指向的娃娃能否嵌套该娃娃
            List pre = Judege(allLinks[kk], scHead->next);
            if (pre)//可以插入,pre是可以插入的节点的前一个节点
            {
                //将scHead->next从原链表中删除
                List tmp = scHead->next;
                scHead->next = tmp->next;
                //将scHead->next插入新链表
                tmp->next = pre->next;
                pre->next = tmp;
            }
            else
            {
                scHead = scHead->next;
            }
        }
        kk++;
    }

    cout << kk << endl;
    for (int x = 0; x < kk; x++)
    {
        release(allLinks[x]);
        allLinks[x] = 0;
    }
    delete head;
    head = 0;
}



int main()
{
    int T;
    int n;
    
    cin >> T; //测试数据组数
    for (int i = 0; i < T; i++)
    {
        //输入数据
        cin >> n;
        List all = new LinkNode;
        all->next = 0;
        List pt = all;
        for (int j = 0; j < n; j++)
        {
            List np = new LinkNode;
            cin >> np->data.w >> np->data.h;
            np->next = 0;
            pt->next = np;
            pt = np;
        }
                
        //处理
        Deal(all);
        
    }
    return 0;
}


Input
第一行包含一个正整数n(1<=n<=100000),表示套娃的个数。
第二行包含n个整数p_1,p_2,...,p_n(0<=p_i<=n),依次表示初始局面中每个套娃的父亲,0表示自由套娃。
第三行包含n个整数q_1,q_2,...,q_n(0<=q_i<=n),依次表示目标局面中每个套娃的父亲,0表示自由套娃。
输入数据保证初始局面和目标局面均合法。
Output
输出一行一个整数,即最小操作步数。
Sample Input
7
3 5 4 0 7 0 0
3 5 0 6 7 0 0
Sample Output
2

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
 
const int N=100100;
 
int fa[N],f[N];
 
bool book[N];
 
int main()
{
    int n=read(),ans=0;
    register int i,j;
    for(i=1;i<=n;++i)fa[i]=read(),book[fa[i]]=1;
    for(i=1;i<=n;++i)f[i]=read(),book[f[i]]=1;
    for(i=1;i<=n;++i){if(fa[i])ans++;if(f[i])ans++;}
    for(i=j=1;i<=n;++i,j=i)if(!book[j])while(fa[j]==f[j]&&fa[j]&&f[j])ans-=2,j=fa[j];
    print(ans);puts("");return 0;
}
/*
7
3 5 4 0 7 0 0
3 5 0 6 7 0 0
2
*/


#include <iostream>
#include <vector>
#include <algorithm>

struct Doll {
    int height;
    int length;
};

bool compareDolls(const Doll& doll1, const Doll& doll2) {
    if (doll1.height == doll2.height) {
        return doll1.length < doll2.length;
    }
    return doll1.height < doll2.height;
}

int findMinNestedGroups(const std::vector<Doll>& dolls) {
    std::vector<int> dp(dolls.size(), 1);
    int maxNestedGroups = 1;

    for (int i = 1; i < dolls.size(); i++) {
        for (int j = 0; j < i; j++) {
            if (dolls[i].height > dolls[j].height && dolls[i].length > dolls[j].length) {
                dp[i] = std::max(dp[i], dp[j] + 1);
            }
        }
        maxNestedGroups = std::max(maxNestedGroups, dp[i]);
    }

    return maxNestedGroups;
}

int main() {
    int t;
    std::cin >> t;

    for (int i = 0; i < t; i++) {
        int m;
        std::cin >> m;

        std::vector<Doll> dolls(m);
        for (int j = 0; j < m; j++) {
            std::cin >> dolls[j].length >> dolls[j].height;
        }

        std::sort(dolls.begin(), dolls.end(), compareDolls);

        int minNestedGroups = findMinNestedGroups(dolls);
        std::cout << minNestedGroups << std::endl;
    }

    return 0;
}

将套娃按照某个属性(例如高度或长度)进行排序,然后逐个判断每个套娃能不能嵌套在前面的套娃内。如果可以嵌套,就将当前套娃放入前面的套娃中,否则就单独创建一个新组。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Doll {
    int height;
    int length;
};

bool compareDolls(const Doll &a, const Doll &b) {
    if (a.height == b.height) {
        return a.length < b.length;
    }
    return a.height < b.height;
}

int main() {
    int t;
    cin >> t;

    while (t--) {
        int m;
        cin >> m;

        vector<Doll> dolls(m);
        for (int i = 0; i < m; ++i) {
            cin >> dolls[i].height >> dolls[i].length;
        }

        sort(dolls.begin(), dolls.end(), compareDolls);

        vector<int> dp(m, 1);  // dp[i] represents the minimum nesting count ending with doll i

        for (int i = 1; i < m; ++i) {
            for (int j = 0; j < i; ++j) {
                if (dolls[i].length > dolls[j].length) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
        }

        int maxNesting = 0;
        for (int i = 0; i < m; ++i) {
            maxNesting = max(maxNesting, dp[i]);
        }

        cout << maxNesting << endl;
    }

    return 0;
}

将上述代码保存到一个名为nested_dolls.cpp的文件中,然后使用C++编译器进行编译,例如:

g++ nested_dolls.cpp -o nested_dolls

【以下回答由 GPT 生成】

解决方案

首先,根据给定的数据格式,我们可以把输入部分分解成两部分,分别是读取输入数据和解析输入数据。然后,我们需要分析问题并找出合适的算法来解决。

首先,我们可以使用动态规划的思想来解决这个问题。我们可以假设套娃的高度和长度分别为 h 和 w。那么,我们可以定义一个二维数组 dp,dp[i] 表示以第 i 个套娃为最外层套娃时,最多可以嵌套的组数。那么,我们可以得到如下的状态转移方程:

dp[i] = max(dp[i], dp[j] + 1) if w[i] > w[j] and h[i] > h[j]其中 0 <= j < i

上述的状态转移方程表示,如果第 i 个套娃能够嵌套到第 j 个套娃内部,那么以第 j 个套娃为最外层套娃时,最多可以嵌套的组数加上 1,就是以第 i 个套娃为最外层套娃时,最多可以嵌套的组数。

那么,我们可以按照如下的步骤来解决这个问题:

  1. 首先读取 t 的值,表示数据组数
  2. 对于每一组数据,执行以下步骤:
  3. 读取 m 的值,表示套娃的数量
  4. 创建一个空白的二维数组 dp,大小为 m
  5. 读取套娃的高度和长度,并存储到一个列表中
  6. 对于每一个套娃 i,执行以下步骤:
    1. 初始化 dp[i] 的值为 1
    2. 对于每一个套娃 j,执行以下步骤:
      1. 如果 w[i] > w[j] and h[i] > h[j],则执行以下步骤:
        1. 更新 dp[i] 的值为 max(dp[i], dp[j] + 1)
  7. 输出 dp 中的最大值,即为最少嵌套的组数

下面是具体的代码实现:

def compute_min_nested_groups():
    # 读取 t 的值
    t = int(input())

    # 对于每一组数据,执行以下步骤
    for _ in range(t):
        # 读取 m 的值
        m = int(input())

        # 创建一个空白的二维数组 dp
        dp = [1] * m

        # 读取套娃的高度和长度,并存储到列表 dolls 中
        dolls = []
        for _ in range(m):
            w, h = map(int, input().split())
            dolls.append((w, h))

        # 对于每一个套娃 i,执行以下步骤
        for i in range(m):
            # 对于每一个套娃 j,执行以下步骤
            for j in range(i):
                # 如果 w[i] > w[j] and h[i] > h[j],则执行以下步骤
                if dolls[i][0] > dolls[j][0] and dolls[i][1] > dolls[j][1]:
                    # 更新 dp[i] 的值
                    dp[i] = max(dp[i], dp[j] + 1)

        # 输出最少嵌套的组数
        print(max(dp))


# 调用函数计算最少嵌套的组数
compute_min_nested_groups()

这样,我们就可以根据给定的输入数据,计算出最少能嵌套的组数了。

请注意,由于输入数据规模比较大,为了保证程序的运行效率,可以使用动态规划的方法,利用数组来存储中间结果并减少重复计算。这样可以大大提高程序的性能。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

引用 皆我百晓生 小程序回复内容作答:
这个问题可以使用动态规划的方法来解决。我们可以根据套娃的高度或长度对它们进行排序,然后计算最长递增子序列的长度。

下面是C++实现的示例代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 定义套娃的结构体
struct Doll {
    int width;
    int height;
};

// 比较函数,按照高度排序
bool compare(Doll a, Doll b) {
    return a.height < b.height;
}

int main() {
    int t; // 数据组数
    cin >> t;

    while (t--) {
        int m; // 套娃数量
        cin >> m;

        vector<Doll> dolls(m);
        for (int i = 0; i < m; i++) {
            cin >> dolls[i].width >> dolls[i].height;
        }

        // 按照高度进行排序
        sort(dolls.begin(), dolls.end(), compare);

        // 定义dp数组,存储最长递增子序列的长度
        vector<int> dp(m, 1);

        // 动态规划计算最长递增子序列的长度
        for (int i = 1; i < m; i++) {
            for (int j = 0; j < i; j++) {
                if (dolls[i].width > dolls[j].width) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
        }

        // 找到dp数组中的最大值,即最少能嵌套的组数
        int maxLen = 0;
        for (int i = 0; i < m; i++) {
            maxLen = max(maxLen, dp[i]);
        }

        cout << maxLen << endl;
    }

    return 0;
}

给定输入样例为:

2
2
10 20
20 30
3
10 30
20 20
30 10

对应的输出样例为:

1
3

希望这个示例代码对你有帮助,如有任何疑问,请随时提问。

结合GPT给出回答如下请题主参考
这是一个典型的最长上升子序列问题(Longest Increasing Subsequence,简称LIS)。我们可以将套娃按照长度或高度进行排序,然后求解其长度/高度的最长上升子序列即可得到最多能够嵌套的套娃数量。具体的实现可以使用动态规划或二分查找等算法来实现,时间复杂度为O(nlogn)。


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Doll {
    int height;
    int length;
};

bool compareDolls(const Doll& a, const Doll& b) {
    if (a.height == b.height)
        return a.length < b.length;
    return a.height < b.height;
}

int main() {
    int t;
    cin >> t;

    while (t--) {
        int m;
        cin >> m;

        vector<Doll> dolls(m);
        for (int i = 0; i < m; ++i) {
            cin >> dolls[i].height >> dolls[i].length;
        }

        sort(dolls.begin(), dolls.end(), compareDolls);

        vector<int> dp(m, 1);
        int maxNesting = 1;

        for (int i = 1; i < m; ++i) {
            for (int j = 0; j < i; ++j) {
                if (dolls[i].length > dolls[j].length) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            maxNesting = max(maxNesting, dp[i]);
        }

        cout << maxNesting << endl;
    }

    return 0;
}

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632