DAG上的动态规划

DAG模型:有n个矩形,每个矩形用两个整数a,b描述,表示长和宽,矩形(a,b)可以嵌套在矩形(c,d)中,当且仅当a小于c,b小于d或b小于c,a小于d。要解决的问题就是从众多矩形中选出最多的矩形,使其可以按要求排成一列,若有多解,矩形编号的字典序要尽可能小。
分析:按照书上的分析很简单易懂,也容易操作,只是有很多的细节需要注意,这个解法要好好学习,很多问题都会涉及最长或最短路径问题
状态转移方程为:
d(i)=max{d(j)+1|(i,j)∈E}


具体代码:`

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxx=100;
int G[maxx][maxx];
struct juxing
{
     char a;            //矩形的序号
     int l,w;           //矩形的长宽
};
juxing ar[maxx];
int dp[maxx];      //dp[i]表示从i出发得到的最大长度
int n;
int DP(int i)
{
     int &ans=dp[i];
     if(ans>0)
          return ans;
     ans=1;
     for(int j=1 ;j<=n;j++)
          if(G[i][j])
          {
               ans=max(ans,DP(j)+1);
          }
     return ans;
}
void printf_ans(int i)
{
     cout<<ar[i].a<<" ";
     for(int j=1;j<=n;j++)
          if(G[i][j]&&dp[i]==dp[j]+1)
          {
               printf_ans(j);
               break;
          }
}
int main()
{
     cin>>n;
     memset(dp,0,sizeof(dp));
     memset(G,0,sizeof(G));
     for(int i=1;i<=n;i++)
     {
          cin>>ar[i].a>>ar[i].l>>ar[i].w;
          if(ar[i].l<ar[i].w)
          {
               int temp=ar[i].l;
               ar[i].l=ar[i].w;
               ar[i].w=temp;
          }
     }
     for(int i=1;i<=n;i++)         //建立邻建图
     {
          for(int j=1;j<=n;j++)
          {
               if(ar[i].l>ar[j].l&&ar[i].w>ar[j].w)
                    G[i][j]=1;
          }
     }
     for(int i=1;i<=n;i++)
     {
          dp[i]=DP(i);
     }
     int answer=0,flag=0;
     for(int i=1;i<=n;i++)
     {
          if(answer<dp[i])
          {
               answer=dp[i];
               flag=i;
          }
     }
     cout<<answer<<endl;
     cout<<endl;
     printf_ans(flag);
     for(int i=1;i<=n;i++)
          cout<<dp[i]<<" ";
     cout<<endl;
     return 0;
}

整个代码在打印方案有点问题,不过书中的这种方法很好用

void print_ans(int i)
{
printf(“%d “,i);
for(int j=1;j<=n;j++)
if(G[i][j]&&d[i]==d[j]+1)
{
print_ans(j);
break;
}
}
“`

在解决这个问题上,按照书上的思路很好理解,但是具体实现时就有点难,自己的动手能力还不强,得多练,不过,我感觉如果每个问题都多问几个问题,多去思考一些问题,对自己理解更有帮助,会更加明白都是套路!!!Ok 第一篇博客诞生,以后继续写,写给自己看,自己比较菜,有些不对的地方,望各路大神指出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值