第十四個目標 dp 樹狀陣列 線段樹

2021-09-08 04:06:12 字數 3575 閱讀 5520

problem 2236 第十四個目標

目暮警官、妃英里、阿笠博士等人接連遭到不明身份之人的暗算,柯南追蹤傷害阿笠博士的**,根據幾起案件現場留下的線索發現**按照撲克牌的順序**。在經過一系列的推理後,柯南發現受害者的名字均包含撲克牌的數值,且撲克牌的大小是嚴格遞增的,此外遇害者與毛利小五郎有關。

為了避免下乙個遇害者的出現,柯南將可能遭到暗算的人中的數字按關聯程度排列了出來,即順序不可改變。柯南需要知道共有多少種可能結果,滿足受害人名字出現的數字嚴格遞增,但是他柯南要找出關鍵的證據所在,所以這個任務就交給你了。

(如果你看不懂上面在說什麼,這題是求乙個數列中嚴格遞增子串行的個數。比如數列(1,3,2)的嚴格遞增子串行有(1)、(3)、(2)、(1,3)、(1,2),共5個。長得一樣的但是位置不同的算不同的子串行,比如數列(3,3)的答案是2。)

多組資料(<=10),處理到eof。

第一行輸入正整數n(n≤100 000),表示共有n個人。

第二行共有n個整數ai(1≤ai≤10^9),表示第i個人名字中的數字。

每組資料輸出乙個整數,表示所有可能的結果。由於結果可能較大,對1 000 000 007取模後輸出。

3 1 3 2

5 福州大學第十三屆程式設計競賽

題解:dp的思路很好想,dp[i]代表i結尾的遞增序列的個數;

dp[i] = 1 + sum(j < i, a[j] < a[i]);

看到sum(dp[j]),aj < a[i],我們很容易想到樹狀陣列;由於數字過大,那麼我們離散化下就好了;

**:

#include#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 100010

;int

dp[maxn];

inta[maxn], b[maxn];

inttree[maxn];

typedef

long

long

ll;const

int mod = 1e9 + 7

;int lowbit(int x)

void update(int i, intx)}

int sum(int

i)

return

ans;

}int

main()

sort(a, a +n);

memset(dp,

0, sizeof

(dp));

memset(tree,

0, sizeof

(tree));

ll ans = 0

;

int k = unique(a, a + n) -a;

for (int i = 0; i < n; i++)

for(int i = 0; i < n; i++)

printf(

"%lld\n

", ans %mod);

}return0;

}

比賽的時候剛開始想著用優先佇列優化的,沒什麼用,還是超時;

**:

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 100010

;int

dp[maxn];

inta[maxn];

inttree[maxn];

typedef

long

long

ll;const

int mod = 1e9 + 7

;struct

node

};int

main()

memset(dp,

0, sizeof

(dp));

ll ans = 0

; priority_queue

q, q1;

node x;

for (int i = 1; i <= n; i++)

while(!q1.empty())

}for(int i = 1; i <= n; i++)

printf(

"%lld\n

", ans %mod);

}return0;

}

線段樹又寫了下,發現還是用二分好,用了結構體各種錯。。。

**:

#include#include

#include

#include

#include

using

namespace

std;

#define ll root<<1

#define rr root<<1|1

#define lson ll,l,mid

#define rson rr,mid+1,r

const

int mod = 1e9 + 7

;const

int maxn = 200100

;typedef

long

long

ll;ll tree[maxn

<< 2

];ll dp[maxn];

void pushup(int

root)

void update(int root, int l, int r, int a, int

b)

if(mid >=a)

update(lson, a, b);

else

update(rson, a, b);

pushup(root);

}ll ans;

void query(int root, int l, int r, int a, int

b) ll ans = 0

;

if(mid >=a)

query(lson, a, b);

if(mid query(rson, a, b);

return;}

inta[maxn], b[maxn];

intmain()

sort(a, a +n);

memset(tree,

0, sizeof

(tree));

memset(dp,

0, sizeof

(dp));

int k = unique(a, a + n) -a;

for(int i = 0; i < n; i++)

printf(

"%lld\n

", tree[1] %mod);

}return0;

}

第十四周 陣列的排序

檔名稱 完成日期 2013年 12月2日 版本號 v1.0 對任務及求解方法的描述部分 輸入描述 問題描述 程式輸出 問題分析 演算法設計 冒泡法 include using namespace std void bubble sort int arr,int num void output arr...

第十四周 陣列類模板

問題及 完成日期 2016 6 2 include include include using namespace std template 陣列類模板定義 class array template array array int sz 建構函式 template array array 析構函式 ...

第十四周專案1 陣列大折騰

1.5.檔名稱 7.完成日期 2013年 11月 27日 8.版本號 v1.0 9.對任務及求解方法的描述部分 10.輸入描述 任務1 建立乙個長度為20的整型陣列,通過鍵盤輸入後20個元素的值,從前往後 從第0個到第19個 輸出陣列中元素的值,每5個元素換一行。11.任務2 由後往前 由第19個元...