bzoj 1044 HAOI2008 木棍分割

2022-07-22 21:12:24 字數 1373 閱讀 1910

2016-06-20

第一問是個二分的經典入門題

第二問很容易發現乙個dp f[i][j]前i個木棍分j次合法方案數,f[i][j]=f[k][j-1]+...+f[i-1][j-1]; 但這樣時間複雜度是o(mn^2),空間複雜度是o(mn) 但我們發現對於相同的j隨著i的增加,對應的k也增加,那我們可以根據這個單調性,用字首和來做到轉移複雜度為o(1),空間可以用滾動陣列來解決,本來我偷懶用short int開陣列,不用滾動陣列。結果t了一半,早就聽說陣列大了會使程式變慢,今天我可算知道了,淚。。。。。

1 #include2 #include3 #include4 #include5 #include6 #include7

#define m 100008

8#define ll long long

9#define mo 10007

10using

namespace

std;

11ll read()

1222

short

int f[50010][2

];23

int n,m,a[50009],l,r,ans,b[50009],p=1

,q;24

bool pan(int

x)2535}

36if(sum<=m)

37return1;

38return0;

39}40int

main()

4150

for(;l<=r;)

5158

else

59 l=mid+1;60

}61 printf("

%d "

,ans);

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

63 a[i]+=a[i-1

];64

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

65if(a[i]<=ans)

66 f[i][p]=1;67

int an=f[n][p];

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

69 b[i]=f[i][p]+b[i-1

];70

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

7181

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

82 b[j]=f[j][q]+b[j-1

];83

swap(p,q);

84 an=(an+f[n][p])%mo;85}

86 printf("

%d\n

",an);

87return

bzoj1044 HAOI2008 木棍分割

傳送門 第一問隨便二分就過了,此處略去。第二問dp f i j 前i根木棍,砍了j刀的方案數。轉移方程很顯然,此處略去。我們可以滾掉一維。但是轉移要o n 2m 顯然要t 於是我們可以用單調佇列 字首和優化轉移,使得時間複雜度降為o nm 然後就過了。include include include ...

BZOJ 1044 HAOI2008 木棍分割

注意可以且m次,即分成m 1段。所以先讓m加上1。先做乙個簡單的二分答案算出最小的最大值。然後可以得到乙個o mn 2 的dp。發現dp可以通過字首和把時間複雜度優化為o nm 通過滾掉記錄m的那一維,把空間複雜度優化為o n include define left leftt using name...

BZOJ 1044 HAOI2008 木棍分割

bzoj 1044 haoi2008 木棍分割 二分答案 dp 有n根木棍,第i根木棍的長度為li,n根木棍依次鏈結了一起,總共有n 1個連線處.現在允許你最多砍斷m個連 接處,砍完後n根木棍被分成了很多段,要求滿足總長度最大的一段長度最小,並且輸出有多少種砍的方法使得總長 度最大的一段長度最小.並...