K排列問題 2 集合動規)

2021-07-29 11:11:07 字數 1390 閱讀 9740

時間限制:1秒  記憶體限制:64m
【問題描述】

在1..n的排列中,若a-b≥k(1≤a,b≤n),則a必須排在b之後。

現在給出n和k,請計算符合條件的排列數。

【輸入格式】

包含若干組測試資料,每組佔一行,每行兩個整數:n和k。

【輸出格式】

若干行,對應輸入的測試資料,表示方案數,這個數可能很到,只須輸出mod 20080814的結果。

【輸入樣例】

5 2

5 4

【輸出樣例】

8 60

【資料範圍】

30%的資料滿足:1≤n≤10

30%的資料滿足:1≤n≤1000, 1≤k≤10

【**】

對於第一組測試資料:n=5,k=2,則滿足條件的排列有如下8個:

1 2 3 4 5

1 2 3 5 4

1 2 4 3 5

1 3 2 4 5

1 3 2 5 4

2 1 3 4 5

2 1 3 5 4

2 1 4 3 5

這道題讓我非常漲姿勢,同樣這也是一類問題的代表。

我們可以發現k是不大於10的,所以這肯定是我們的突破點。我們假設前i個已經排好,第i+1個沒排,那麼第i+k+1個以及以後的就不可能排好了。

所以我們只需要看這k個數的情況,這樣就能壓縮了,我們設d[i][a]為前i個已經排好,中還未排的集合為a。

如果i+1不在集合中,那麼狀態直接轉換成d[i+1][a/2+(1< < k-1)]相當於直接把i+1加進去,然後把集合往前移一位再把i+k+1加入到集合中。

如果i+1在集合中,我們可以列舉乙個在集合中的數,加入到佇列裡去。

注意:i應從0到n, a應從all到0(因為f(i,b)=sigma(f(i,a)),b是a的子集,所以應在a已經計算的情況下再計算b)

**如下:

#include

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

const

int maxn=1005;

const ll mod=20080814;

int n,k,all;

ll d[maxn][1

<<11],b[20];

void init()

else

d[i+1][t/2+b[k]]=(d[i+1][t/2+b[k]]+d[i][t])%mod;}}

}int main()

MongoDB學習2 集合

集合就是 mongodb 文件組,類似於 rdbms 關聯式資料庫管理系統 relational database management system 中的 集合存在於資料庫中,集合沒有固定的結構,這意味著你在對集合可以插入不同格式和型別的資料,但通常情況下我們插入集合的資料都會有一定的關聯性。比如...

2 集合常用操作

集合的宣告 空集 data1 set print data1,type data1 set 有成員的集合 data2 print data2,type data2 add 新增成員,成員如果已經存在,則會被去重 update 新增成員,成員如果已經存在,則會被去重 data1 data1.add c...

2 7 集合劃分問題

問題描述 n 個元素的集合可以劃分為若干個非空子集。例如,當 n 4 時,集合可以劃分為 15 個不同的非空子集如下 程式設計任務 給定正整數 n,計算出 n 個元素的集合可以劃分為多少個不同的非空子集。資料輸入 由檔案 input.txt 提供輸入資料。檔案的第 1 行是元素個數 n。結果輸出 程...