題意: 馬在(1,1)走到(n,m)有些地方設定了障礙物不能走。。問方案總數是多少?
思路:題外話考慮如果不是馬是兵。。其實就是一道cf的原題。。。
是馬的話其實和兵的思路是一樣的,唯一稍微有困難的是要求出(1,1)到(x,y)的方案數 結論是 lucas ( (x+y)/3 , ((x+y)/3-abs(x-y))/2 )
因為是大組合數取模,顯然想到盧卡斯定理,這裡就不做詳細說明。。。
接下來就是容斥部分。。。首先r有100.。。。肯定不是2^100這樣容斥。。太蠢了。。。這個使用的是類似dp的方法,把每個障礙物的最終方案數求出來。。那兩個和三個舉栗子。。兩個肯定是第二個的方案數減去第乙個的方案數乘以第乙個到第二個的方案數 。。那接下來看第三個。。其實就是第三個的方案數減去第乙個的方案數乘以第乙個到第三個的方案數並且減去
第二個的方案數乘以第二個到第三個的方案數 。。仔細推敲一下用集合的方法表示一下,我們會發現這恰好就是乙個容斥的過程。。歸納一下我們就知道了到第n個的方法了。。。
最後!需要注意的是要判斷終點有沒有障礙物。。障礙物之間是否可以到達!!!(當時wa到死。。)
**:
#include #include #include #include #define max 105
using namespace std;
typedef long long ll;
const ll mod = 110119;
const ll p= 110119;
ll dp[max];
long long h,w,n;
struct node
bool operator == ( const node & a ) const
}p[max];
long long fac[p+10];
void init()
long long pow(long long a, long long b)
return ans;
}long long c(long long n, long long m)
long long lucas(long long n, long long m)
bool ok(node t)
int main ()
}p[cnt].x = h , p[cnt].y = w;
if(!ok(p[cnt]))
sort ( p , p+cnt+1 );
if(cnt>=1&&p[cnt-1]==p[cnt])
memset ( dp , 0 , sizeof ( dp ));
for ( int i = 0; i <= cnt ; i++ )
}printf ( "case #%d: %lld\n" ,cas++, dp[cnt] );
}}
HDU 5794 容斥原理 Lucas
題意 馬在 1,1 走到 n,m 有些地方設定了障礙物不能走。問方案總數是多少?思路 題外話考慮如果不是馬是兵。其實就是一道cf的原題。是馬的話其實和兵的思路是一樣的,唯一稍微有困難的是要求出 1,1 到 x,y 的方案數 結論是 lucas x y 3 x y 3 abs x y 2 因為是大組合...
hdu 4336 容斥原理
按照解題報告的提示,用容斥原理實現 for int j bg 1 j另解 概率dp,康哥指導的 include include includeusing namespace std double f 1 21 gl 22 int main int i,j,k,n double fz,fm while...
hdu4135 容斥原理
題意 給出a,b,n,求出 a,b 範圍內與n互素的數字的個數。即b範圍內的不與n互素的數減去a範圍內不與n互素的數,把 1,a 1,b 中不與n互素的數分別求出來,再減掉就是和n互素的數了。那麼首先將n分解質因數,因子和因子的倍數可以被除盡,一定不與n互素,把這些數都記下來,篩法求素數即可 然後把...