uva 103 Stacking Boxes 动态规划

uva--103--Stackint Boxes

Problem : 给你n个m维的多边形,当初存在一个顺序,使得两个多边形中的一个多边形的每条边都小于另一个

多边形,就说这个多边形能嵌套在另一个多边形里面,求最多存在多少个这样的连续的多边形使得s1>>s2>>...>>sn;

Way:  动态规划:把每个多边形看成一个点,当一个多边形能嵌套在另一个中,则连一条有向边,则变成了找有向图

的最长路径,dp[i]表示从i出发的最长的路径,则max(dp[i] | 1<=i<=n)则是最终答案,dp[i] = max(dp[i], dp[j]+1)(j指和i相邻的

多边形);

//
//  main.cpp
//  Calmeii
//
//  Created by Calmeii on 14-5-5.
//  Copyright (c) 2014年 apple. All rights reserved.
//

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 31

int G[MAXN][MAXN], val[MAXN][MAXN], dp[MAXN], n;

int dfs(int i)
{
    if (dp[i] > 0){     //表示已经求过,直接返回即可
        return dp[i];
    }
    dp[i] = 1;
    for (int j = 1; j <= n; j++){
        if (G[i][j]){
            dp[i] = max(dfs(j)+1, dp[i]);
        }
    }
    return dp[i];
}
int first;
void print_ans(int i)
{
    if (first) first = 0;
    else printf(" ");
    printf("%d", i);
    
    for (int j = 1; j <= n; j++){
        if (G[i][j] && dp[i] == dp[j] + 1){
            print_ans(j);
            break;
        }
    }
}
int main()
{
    int m;
    
    while (scanf("%d%d", &n, &m) != EOF)
    {
        for (int i = 1; i <= n; i++){
            for (int j = 0; j < m; j++){
                scanf("%d", &val[i][j]);
            }
            sort(val[i], val[i]+m);
        }
        memset(G, 0, sizeof(G));
        memset(dp, 0, sizeof(dp));
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++){
                int k;
                for (k = 0; k < m; k++){
                    if (val[i][k] >= val[j][k]){    //表示不能构成边
                        break;
                    }
                }
                if (k == m){
                    G[i][j] = 1;    //表示i到j存在有向边
                }
            }
        }
        int ans = 0;    //保存最大的值
        for (int i = 1; i <= n; i++){
            ans = max(ans, dfs(i));
        }
        printf("%d\n", ans);
        for (int i = 1; i <= n; i++){
            if (ans == dp[i]){
                first = 1;
                print_ans(i);
                break;      //只需打印一种情况
            }
        }
        printf("\n");
    }
    
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值