现在的位置: 首页 > 综合 > 正文

UVA – 10599(求LIS,记录路径数)

2018年03月17日 ⁄ 综合 ⁄ 共 1031字 ⁄ 字号 评论关闭

本题目一开始直接不敢用把所有点排序求LIS和LIS的个数,点最多有10000会超时的,但交上去不到0.1秒;可能后台数据点最多也就1000个左右;

求LIS不用详解了,很水的两重循环求得,在此过程中保留以每个点为终点的最大长度串的个数;还要在记录一个前驱即可打印路径;

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 10005;

int d[maxn],rec[maxn],cnt[maxn],n,m,maze[105][105],a[maxn];
void print_ans(int j){
   if(rec[j] !=-1)
     print_ans(rec[j]);
   printf(" %d",a[j]+1);
}
int main()
{
    int kase=1;
    while(scanf("%d %d",&n,&m)==2){
         if(n==-1) break;
         int x,y;
         memset(maze,0,sizeof(maze));
         while(scanf("%d %d",&x,&y)&&x&&y){
            maze[x][y]=1;
         }
         int kk=0;
         for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++){
             if(maze[i][j]){
                a[kk++]=(i-1)*m+j-1;
             }
         }
         int flag =false;
         if(a[kk-1]!=n*m-1){
                a[kk++] = n*m-1;
                flag = true;
         }
         for(int i=0;i<kk;i++) d[i] = 1;

         for(int i=0;i<kk;i++){
            cnt[i] = 1;  rec[i] = -1;
            for(int j=0;j<i;j++){
                if(a[j]%m <= a[i]%m){
                    if(d[j]+1>d[i]){
                        d[i]=d[j]+1;
                        cnt[i] = cnt[j];
                        rec[i] = j;
                    }
                    else if(d[j]+1==d[i]){
                        cnt[i] += cnt[j];
                    }
                }
            }
         }
         if(flag) d[kk-1]--;
         printf("CASE#%d: %d %d",kase++,d[kk-1],cnt[kk-1]);
         if(flag)
            print_ans(rec[kk-1]);
         else print_ans(kk-1);
         printf("\n");
    }
    return 0;
}

抱歉!评论已关闭.