NYOJ 16 矩形嵌套(动态规划 or 贪心)

来源:互联网 发布:mp3软件下载录音 编辑:程序博客网 时间:2024/06/05 20:53

题目意思很清晰  求最多的嵌套个数  相等不能被嵌套

本文提供两种解法 

第一种解法对于 矩形边长较小时效果比较好 但是如果矩形边长特别大则不能有效求解

第一种解法是dp做的  

定义dp[i][j] 为边长为I和j的矩形 最多能嵌套多少个矩形 

状态转移过程是这样来的  当前状态是由比当前矩形的宽小一 或者比当前矩形的长小一的两种状态的较大者来的 

如果给定的这些矩形中存在一个比当前矩形长宽都小一的矩形  那么 dp[I][j] = max(dp[I][j] , dp[I - 1][j - 1] + 1);

保存这些矩形信息的方式是邻接表  有点桶排序的意思 嗯 就是这样


#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N = 104;int arr[N][N], dp[N][N];int main(){    int n, t;    cin >> t ;    while (t -- ) {        cin >> n;        memset(arr , 0, sizeof(arr));        memset(dp , 0, sizeof(dp));        int a, b;        for (int i = 0; i < n; i ++) {            cin >> a >> b;            arr[a][b] ++;            arr[b][a] ++;        }        int maxx = 0;        for(int i = 1; i < N; i ++) {            for (int j = 1; j < N; j ++) {                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);                if(arr[i - 1][j - 1])                    dp[i][j] = max(dp[i][j] , dp[i - 1][j - 1] + 1);            }        }        cout << dp[N - 1][N - 1] << endl;    }}/*41 11 22 13 2*/


当然还有显而易见的方法二 就是贪心了  

首先我们按照矩形的长为第一顺序  宽为第二顺序 来排序 然后找出每个矩形能嵌套多少矩形 在找出最大的内个值就行了

#include <iostream>#include <algorithm>#include <cstring>using namespace std;struct Node{    int length, width;}rectangle[1005];bool cmp(const Node &a, const Node &b){    if(a.length != b.length)        return a.length < b.length;    else        return a.width < b.width;}bool judge(const Node &a, const Node &b){    if(b.length  > a.length && b.width > a.width || b.length > a.width && b.width > a.length)return true;    else return false;}int main(){    int t, n, dp[1005];    cin >> t ;    while ( t -- ) {        cin >> n ;        for (int i = 0; i < n; i ++) {            cin >> rectangle[i].length >> rectangle[i].width ;            if(rectangle[i].length < rectangle[i].width)                swap(rectangle[i].length , rectangle[i].width);        }        sort(rectangle , rectangle + n, cmp);        int ans = 0;        for (int i = 0; i < n; i ++) {//枚举起点           // Node temp = rectangle[i];            dp[i] = 1;            for(int j = 0; j < i; j ++) {//初始和结束的边界很重要 慢慢体会吧                if(judge(rectangle[j] , rectangle[i])) {                    dp[i] = max(dp[i], dp[j] + 1);                }            }            ans = max(ans , dp[i]);        }        cout << ans << endl;    }}



原创粉丝点击