t1:這題較為簡單。
只需求出去掉每乙個位置之後逆序對個數減少多少個,然後推一下式子就好了。
t2:這題比較靈活。
我們把所有的字串放在乙個矩陣上,然後從左往右考慮每一列,我們發現其實所有字串就是在不斷地分組。把每一列中字母相同的字串分到同一組,然後在看下一列。最終m列之後每乙個字串都別分到了不同的組,這樣就是合法的。
那麼我們就可以dp了。設f[i][l][r][c]表示現在處理到第i列,l~r行最大的字元填c的且當前l~r行的字典序有嚴格保證的方案數。(注意我們是從m往1處理的)。
在轉移時,我們列舉乙個r1和d,表示第i列r+1~r1行填d,接著我們就f[i][l][r1][d]+=f[i][l][r][c]*f[i+1][r+1][r1][e]。由於e的任意性,我們可以邊求f邊求和,那麼轉移時我們就不用列舉e了。
這樣的複雜度時能過的。但是還有一些細節要注意,比如說我們要判斷r+1~r1填d是否合法,還有就是在l~r都能填c的情況下,我們要把g[i+1][l][r]作為f[i][l][r][c]的初值(g就是f的和)。
細節較多,貼一下**:
t3:這是一道偏數學的題目。#include#include#include#define ll long long
#define maxn 60
#define maxm 30
#define maxv 30
#define mod 990804011
ll a[maxn][maxm],f[maxm][maxn][maxn][maxv],g[maxm][maxn][maxn],n,m,ans;
char a1[maxn][maxm];
int main()
else a[i][j]=-1;
for(l=1;l<=n;l++)
if(a[l][m]!=-1)f[m][l][l][a[l][m]]=1;
else
for(c=1;c<=26;c++)f[m][l][l][c]=1;
for(c=0;c<=26;c++)
for(l=1;l<=n;l++)
for(r=l;r<=n;r++)
for(i=m-1;i>=1;i--)
for(c=0;c<=26;c++)
for(l=1;l<=n;l++)
g[i][l][r]=(g[i][l][r]+f[i][l][r][c])%mod;
}}printf("%lld",g[1][1][n]);
}
首先我們把所有x[i]減1,然後發現f就等於從(0,0...,0)走到(x[1],x[2],...,x[k])的方案數%2。
然後我們就可以開始推式子:
首先對於二維情況:f=c(x1+x2,x2)。
那麼擴充套件到k維的情況就是:
現在就是要求f的奇偶性。首先很容易得出n!中2因子的個數=
這時又到感性理解的時候了:如果存在某個x[i]和x[j]相加時在二進位制狀態下發生了進製,那麼f一定含有2因子,即f的貢獻為0。
這其實不難理解。那麼現在我們可以得出結論,如果想要f對答案有貢獻,那麼所有x的二進位制位上最多只能有乙個1(即不能進製)。
那麼就可以數字+狀壓dp了。設f[i][s]表示當前到第i位,其中s狀態下的x前面已經頂到了上限(就是數字dp的常見套路)的方案數。列舉所有x的第i-1位填什麼,即乙個新的01集合s1,判斷是否合法後轉移即可。
最後要優化一下才能過。
NOIP提高組 矩陣
在麥克雷的面前出現了乙個有n m個格仔的矩陣,每個格仔用 或 表示,表示這個格仔可以放東西,則表示這個格仔不能放東西。現在他拿著一條1 2大小的木棒,好奇的他想知道對於一些子矩陣,有多少種放木棒的方案。因為棍子是1 2的,所以很容易就能發現,兩個被分割的塊,除了跨越兩個塊擺放木棍的方案數會對答案有影...
NOIP提高組2005 過河
過河 river 問題描述 在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長度 座標為0的點表示橋的起點,座標為l的...
NOIP提高組 20151029模擬
其實這套題目並不算太難,但是還是發揮不了100 水平。第一題直接線性篩法,求出質數,然後就可以判斷乙個數是否為質數了。這道題還可以用miller rabin去求,後者的速度較快,如果資料再大些,就要使用後者了。第二題,比賽時發現了,當n 7時,答案會每四個一迴圈,但是就沒有繼續往下想,其實想下去會想...