UVa OJ 103

1、又是一道DP,一次AC,发现DP题只要你会做就不会错。。。这点比那些用BT数据坑人的模拟题好多了。

2、本题可以转化为DAG上任意起点的最长路问题,易错的地方主要有:k和n容易搞混,k是盒子数而n是盒子维数,这让习惯以n来计数的我很不适应;最佳答案要单独用path数组保存,否则会被覆盖;注意交题的时候把freopen给注释掉。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[40][15],G[40][40],d[40],path[40];
int k,n,maxn,maxi;
bool is_smaller(int *a,int *b){
    for(int i=0;i<n;i++)
       if(a[i]>=b[i]) return false;
    return true;
}
void init(){
      memset(a,0,sizeof(a));
      memset(G,0,sizeof(G));
      memset(d,0,sizeof(d));
      for(int i=0;i<k;i++)
        for(int j=0;j<n;j++)
            scanf("%d",&a[i][j]);
      for(int i=0;i<k;i++)
            sort(a[i],a[i]+n);
      for(int i=0;i<k;i++)
        for(int j=0;j<k;j++)
            if(i!=j&&is_smaller(a[i],a[j]))
                G[i][j]=1;
}
int dp(int i){
    int &ans=d[i];
    if(ans>0)return ans;
    ans=1;
    for(int j=0;j<k;j++)
      if(G[i][j]) ans=max(ans,dp(j)+1);
    return ans;
}
void print_ans(int i){
    printf("%d ",i+1);
    for(int j=0;j<k;j++) if(G[i][j]&&path[i]==path[j]+1){
        print_ans(j);
        break;
    }
}
int main(){
   //freopen("a.txt","r",stdin);
   while(scanf("%d%d",&k,&n)==2){
       init();
       maxn=0;maxi=0;
       memset(path,0,sizeof(path));
       for(int i=0;i<k;i++){
           memset(d,0,sizeof(d));
           dp(i);
           if(d[i]>maxn){
               maxn=d[i];
               maxi=i;
               memcpy(path,d,sizeof(path));
           }
       }
       printf("%d\n",maxn);
       print_ans(maxi);
       printf("\n");
      }
   return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值