正文

Zju 1787 Tiling Up Blocks2007-01-27 22:25:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/cruxd/22927.html

分享到:

这道题相当的经典,本身就有很多做法,而CQF大牛的做法尤为精妙。

给出一系列零件Si,零件有两个参数Ai Bi。现在将其排序,要求若i>j,则Ai>=Aj Bi>=Bj。也就是前面的两个参数要分别小于等于后面的两个参数。求此队列的最大长度。

那么如果将其投影到二维平面上,对每个零件Ai Bi点计数,那么问题就转换成为从最左下的1 1到左上的100 100,只能向右和向上运动,求运动过程中的访问总和最大值。

因此只要把每个点下面和左面的点比较,大者记入此点总和即可。

今天偶然看了一下排名,ZOJ果然有没落的倾向,而据说POJ越来越繁荣了。

#include <cstdio>
#include <string>

int n, a[101][101], b[101][101], nx, ny, mx, my;

int maxi ( int a, int b )
{
 return a > b ? a : b;
}

void pb ()
{
 //printf ( "%d %d %d %d\n", mx, my, nx, ny );
 int i, k;
 for ( i = nx; i <= mx; i ++ )
 {
  for ( k = ny; k <= my; k ++ )
  {
   printf ( "%d ", b[i][k] );
  }
  printf ( "\n" );
 }
}

void init ()
{
 memset ( a, 0, sizeof (a) );
 memset ( b, 0, sizeof (b) );
 mx = my = 0, nx = ny = 101;
}

int dp ()
{
 int i, k;
 for ( i = nx; i <= mx; i ++ )
 {
  for ( k = ny; k <= my; k ++ )
  {
   b[i][k] = maxi ( b[i - 1][k], b[i][k - 1] );
   if ( a[i][k] ) b[i][k] += a[i][k];
  }
 }
 //pb ();
 return b[mx][my];
}

int main ()
{
 //freopen ( "in.txt", "r", stdin );
 while ( scanf ( "%d", &n ) )
 {
  if ( !n ) 
  {
   printf ( "*\n" );
   break;
  }
  int i, x, y;
  init ();
  for ( i = 0; i < n; i ++ )
  {
   scanf ( "%d %d", &x, &y );
   a[x][y] ++;
   if ( x > mx ) mx = x;
   if ( y > my ) my = y;
   if ( x < nx ) nx = x;
   if ( y < ny ) ny = y;
  }
  printf ( "%d\n", dp () );
 }
 return 0;
}
  

2210940 2007-01-27 21:57:54 Accepted 1787 C++ 00:00.01 472K Crux.D

 

 

阅读(3436) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册