乙個讓單身狗們崩潰的題……
題目大意:
有n件物品,一共取d次,一次取的必須少於m件,問共有多少種取法。(每個物品相同,有多測,對998244353取模)
題解:30%演算法(n,d<=20,m<=10)
簡單的dp。
設f[i][j]為取了i次,共取了j件物品的方案數,則有如下狀態轉移方程:
f[i][j]=∑kk=max(j-m,0)f[i-1][k]
初狀態f[0][0]=1,末狀態為f[d][n]。
時間複雜度o(nmd)。
100%演算法(n,m<=2000,d<=1012)
可以看出d大的嚇人,我們不可能列舉d。
我們首先會想到矩陣快速冪,但是此題的矩陣並不特殊,短時間找規律很難,不易優化成n2級別,但n3的複雜度又承受不起。
我們發現,相對於d,n很小,也就是說最多有n天能取到東西,剩下的天數如同虛設。
我們只考慮這n天內的情況,如上設出f[i][j],則狀態轉移方程為:
f[i][j]=∑kk=max(j-m,1)f[i-1][k]
但是和上面不同,此時的n,m是103級別,不能像上面一樣轉移,用字首和優化可以解決。
下面就是總方案數的求法。
在d天裡,有可能有n/(m-1)~n天當中取到物品,所以總方案數為:
ans=∑i<=n
i=1f[i][n]*c(d,i)
我們發現大組合數不好求,於是打算採用消項法,d!和(d-i)!可以消走,剩下約n項可o(n)求出,分母的i!可以求逆元解決。
值得注意的是,相乘時因數較大,需要需要現將因數取模再相乘,否則會乘暴long long,得到光榮的wa30,只能說資料太強了。
單次複雜度o(nm)。
code:
1 #include2 #include3 #include4view code#define ll long long
5using
namespace
std;
6const ll mod=998244353;7
const ll n=2010;8
intn,m;
9ll d,dp[n][n],f[n],jc[n],inv[n];
10ll qpow(ll x,ll y)
1118
return
ans;19}
20void
pre()
2127}28
intmain()
2944
}45 ll ans=0;46
for(int i=1;i<=n;i++)
52 printf("
%lld\n
",ans);
53}
54return0;
55 }
帥哥美女們能否順手點個推薦。
單身三連之三
這是最終章,永久的思念。題目大意 有n張牌,每張牌兩面都有數字,範圍都在1到2n之間,求最少的反轉次數,使得每張牌朝上的一面的數字各不相同,並求出達到這個效果的方案數。多測,初始時每張牌正面朝上,無解輸出 1 1 題解 20 資料 n 20 直接搜尋即可。100 資料 n 1 105 搜尋複雜度不允...
NOIP三連測總結
近三天舉行了三場考試,好像考得都不咋地,與上一周專題訓練相比相差甚遠。單就分數來說,基本看不下去。基本就在20名左右徘徊。但是,三天以來,從第一天思維僵化忽略各種情況到今天想到第二題正解 雖然寫掛了 個人感覺自己的狀態還是在變好,並且收穫了一些乾貨 1.對於輸入輸出接近longlong的題目,不要因...
我今天表演加班,一連,二連,三連
是為dos提供的有力的除錯,跟蹤程式執行,檢查系統資料的工具程式,它是在字元介面下以單字元命令方式工作。要很好地使用它必須具備一定的彙編程式設計和硬體基本知識的能力,當然,它為組合語言程式設計師提供了有效的除錯手段,它的功能包括以下幾個方面。1.直接輸入 更改 跟蹤 執行匯程式設計序 2.觀察作業系...