Week12 作業選做題(區間dp,狀壓dp)

2021-10-06 23:51:06 字數 1649 閱讀 4357

406簡化一下題意:

要找由[(])四個字元組成的字串的最長子序列,這個子串行必須滿足,所有的括號裡都不能包含單數個另一種括號的一邊(這一邊無法再匹配到另一半)

那麼,這道題就成為了區間dp的典型題。

剛開始遍歷左右括號之間距離為0的情況,再遍歷距離為1,2…n的情況。按順序從左到右遍歷,根據狀態轉移方程:

j=i+len;if(

(s[i]

=='('

&&s[j]

==')')||

(s[i]

=='['

&&s[j]

==']'))

d[i]

[j]=d[i+1]

[j-1]+

2;for

(int k=i;k

)

d[i][j]是從位置i到位置j的符合條件的子串行長度,注意,形如[(])這樣的序列的符合條件的子串行長度為2。

思路:經典狀壓dp,開三個陣列,penal[i](i化為2進製),表示按照i的值決定當前已做作業的扣分情況。比如i為101,表示當前做的作業是第一和第三項。

sum[i]表示完成當前作業需要多少天。

pre[i]記錄作業方案。

求出狀態轉移方程

int penalty=

max(sum[i-(1

<

]+h[j]

.c-h[j]

.d,0);

if(penal[i]

>=penal[i-(1

<

]+penalty)

完整**:

#include

#include

#include

using

namespace std;

struct hwh[16]

;int penal[

1<<16]

,sum[

1<<16]

,pre[

1<<16]

;bool

cmp(hw a,hw b)

void

print

(int x)

intmain()

sort

(h,h+n,cmp)

;int maxx=(1

<

;for

(int i=

1;i<=maxx;i++)}

} cout<

<

print

(maxx);}

return0;

}

Week12作業 E 選做題 2 狀壓dp

馬上假期就要結束了,zjm還有 n 個作業,完成某個作業需要一定的時間,而且每個作業有乙個截止時間,若超過截止時間,一天就要扣一分。zjm想知道如何安排做作業,使得扣的分數最少。tips 如果開始做某個作業,就必須把這個作業做完了,才能做下乙個作業。有多組測試資料。第一行乙個整數表示測試資料的組數 ...

Week12作業 必做題

a給出n個數,zjm想找出出現至少 n 1 2次的數,現在需要你幫忙找出這個數是多少?input 本題包含多組資料 每組資料報含兩行。第一行乙個數字n 1 n 999999 保證n為奇數。第二行為n個用空格隔開的整數。資料以eof結束。output 對於每一組資料,你需要輸出你找到的唯一的數。實現 ...

WEEK12 作業 C 必做題3

東東每個學期都會去寢室接受掃樓的任務,並清點每個寢室的人數。每個寢室裡面有ai個人 1 i n 從第i到第j個宿舍一共有sum i,j a i a j 個人 這讓宿管阿姨非常開心,並且讓東東掃樓m次,每一次數第i到第j個宿舍sum i,j 問題是要找到sum i1,j1 sum im,jm 的最大值...