• dp


    Gerald and Giant Chess 

    Problem's Link:   http://codeforces.com/contest/559/problem/C 


     

    Mean: 

    一个n*m的网格,让你从左上角走到右下角,有一些点不能经过,问你有多少种方法。

    analyse:

    BZOJ上的原题。

    首先把坏点和终点以x坐标为第一键值,y坐标为第二键值排序 。

    令fi表示从原点不经过任何坏点走到第i个点的个数,那么有DP方程:

      fi=Cxixi+yi∑(xj<=xi,yj<=yi)C(xixj)(xixj)+(yiyj)f

    当于枚举第一个遇到的坏点是啥,然后从总方案里减掉。

    然后再利用组合数取模就行。

    (http://blog.csdn.net/popoqqq/article/details/46121519)

    Time complexity: O(N*N)

     

    Source code: 

    /*
    * this code is made by crazyacking
    * Verdict: Accepted
    * Submission Date: 2015-07-22-23.43
    * Time: 0MAXMS
    * MAXMemory: 137KB
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #define mod 1000000007
    #define  Ulong long unsigned long long
    using namespace std;

    const int MAXN = 200005;
    long long h, w, n, ans;
    long long q1[MAXN], q2[MAXN], f[MAXN];
    struct point
    {
         int x, y;
         friend bool operator<( point x1, point y1 )
         {
               if( x1.x != y1.x )return x1.x < y1.x;
               return x1.y < y1.y;
         }
    } a[MAXN];

    long long quick_pow( long long x, long long y )
    {
         long long ans = 1;
         while( y )
         {
               if( y & 1 )ans = ( ans * x ) % mod;
               y >>= 1;
               x = ( x * x ) % mod;
         }
         return ans;
    }

    int main()
    {
         cin >> h >> w >> n;
         for( int i = 1; i <= n; i++ )
               cin >> a[i].x >> a[i].y;
         for( int i = 0; i < MAXN; ++i )
               q1[i] = q2[i] = f[i] = 0;
         q1[0] = q2[0] = 1;
         sort( a + 1, a + n + 1 );
         for( int i = 1; i <= h + w; ++i )
               q1[i] = q1[i - 1] * i % mod;
         q2[h + w] = quick_pow( q1[h + w], mod - 2 );
         for( int i = h + w - 1; i >= 1; i-- )
               q2[i] = q2[i + 1] * ( i + 1 ) % mod;
         ans = q1[h + w - 2] * q2[h - 1] % mod * q2[w - 1] % mod;
         for( int i = 1; i <= n; i++ )
         {
               f[i] = q1[a[i].x + a[i].y - 2] * q2[a[i].x - 1] % mod * q2[a[i].y - 1] % mod;
               for( int j = 1; j < i; j++ )
                     if( a[j].x <= a[i].x && a[j].y <= a[i].y )
                           f[i] -= f[j] * q1[a[i].x + a[i].y - a[j].x - a[j].y] % mod * q2[a[i].x - a[j].x] % mod * q2[a[i].y - a[j].y] % mod;
               f[i] = ( f[i] % mod + mod ) % mod;
               ans = ans - f[i] * q1[h + w - a[i].y - a[i].x] % mod * q2[h - a[i].x] % mod * q2[w - a[i].y] % mod;
         }
         ans = ( ans % mod + mod ) % mod;
         cout << ans << endl;
         return 0;
    }
  • 相关阅读:
    写壳笔记一(加节表)
    cs_forums_GetForumsModeratedByUser///cs_forums_GetUnmoderatedPostStatus
    cs_Favorites_Get///cs_Favorites_GetSections
    cs_Feed_UpdateFeedStatus///cs_FeedPost_GetPost///cs_FeedPost_GetPostFullDetails///cs_FeedPost_UpdatePosts
    又来牢骚一下
    cs_Favorite_Delete///cs_Favorite_Get
    cs_Folder_GetFolders///cs_Folder_GetSummary///cs_Folder_MoveFolder
    cs_Folder_RenameFolder///cs_forums_GetForumMessages///cs_forums_GetForumModerators
    cs_Favorites_GetUsers///cs_Favorites_GetUsersWatching
    cs_Feed_AddFeed///cs_Feed_GetAll
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4669486.html
Copyright © 2020-2023  润新知