正文

Zju 1800 Decorations2007-04-30 22:53:00

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

分享到:

    最近经常性地在关键时刻掉链子。古希腊先哲说,人不会两次跌进同一个坑——确实,我跌进了两个坑,摔的鼻青脸肿。先是在杭电邀请赛上看错范围,把辅助数组开小,幸好同伴火眼金睛;这道题犯的错误几乎一摸一样,一个a[601][101]的数组开成了a[101][601]。最可恨的是这样的错误假如没有意识到,一辈子都找不出来!ZOJ上wrong answer映的我发绿,莫名其妙,怎么也该打出一个RunTimeError吧……结果我的程序几乎被改成BusyCai同学的程序了……

    这类词典型的dp题目倒也差不多,a[i][k]代表了第k个词语在填入第i个位置时的可能总数。只要扫描上一个位置的所有M词语a[i- 1][j],满足情况者加入a[i][k]即可。BusyCai的写法比较好,用每个位置a[i][k]去加到下一个位置a[i + 1][j]。a[i][k]可能为0,节省了很多时间。

#include <cstdio>
#include <string>

int N, L, M, len, a[110][610];
char str[610][11];

void init ()
{
 int i;
 for ( i = 0; i < M; i ++ )
 {
  scanf ( "%s", str[i] );
 }
 memset ( a, 0, sizeof ( a ) );
 len = strlen ( str[0] );
}

int check ( int a, int b )
{
 int i;
 for ( i = 1; i < len; i ++ )
 {
  if ( str[a][i] != str[b][i - 1] )
   return 0;
 }
 return 1;
}

void dp ()
{
 int i, k, j;
 for ( k = 0; k < M; k ++ )
 {
  a[len][k] = 1;
 }
 for ( i = len; i < L; i ++ )
 {
  for ( k = 0; k < M; k ++ )
  {
   if ( a[i][k] )
    for ( j = 0; j < M; j ++ )
    {
     if ( check ( k, j ) )
      a[i + 1][j] += a[i][k];
    }
  }
 }
 int sum = 0;
 for ( k = 0; k < M; k ++ )
 {
  sum += a[L][k];
 }
 printf ( "%d\n", sum );
}

int main ()
{
 //freopen ( "in.txt", "r", stdin );
 while ( scanf ( "%d%d%d", &N, &L, &M ) != EOF )
 {
  if ( N + L + M == 0 )
   break;
  init ();
  dp ();
  //pa ();
 }
 return 0;
}

阅读(3590) | 评论(0)


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

评论

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