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根木棍被分成了很多段,要求滿足總長度最大的一段長度最小,並且輸出有多少種砍的方法使得總長 度最大的一段長度最小.並...