# 【动态规划】bzoj1044: [HAOI2008]木棍分割

## Description

有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连

## Input

输入文件第一行有2个数n,m.接下来n行每行一个正整数Li,表示第i根木棍的长度.n<=50000,0<=m<=min(n-1,10
00),1<=Li<=1000.

## Output

输出有2个数, 第一个数是总长度最大的一段的长度最小值, 第二个数是有多少种砍的方法使得满足条件.

3 2
1
1
10

10 2

## 题目分析

 1 #include<bits/stdc++.h>
2 const int maxn = 1003;
3 const int MO = 998244353;
4
5 int n,m,mxBound,mnBound,ans;
6 int a[maxn],s[maxn],t[maxn],g[maxn][maxn];
7 int f[maxn][maxn];
8 int C[maxn][maxn];
9
11 {
12     char ch = getchar();
13     int num = 0;
14     bool fl = 0;
15     for (; !isdigit(ch); ch = getchar())
16         if (ch=='-') fl = 1;
17     for (; isdigit(ch); ch = getchar())
18         num = (num<<1)+(num<<3)+ch-48;
19     if (fl) num = -num;
20     return num;
21 }
22 bool check(int x)
23 {
24     int cnt = 1, sum = 0;
25     for (int i=1; i<=n; i++)
26         if (sum+a[i] > x) sum = a[i], cnt++;
27         else sum += a[i];
28     return cnt <= m;
29 }
30 int qmi(int a, int b)
31 {
32     int ret = 1;
33     while (b)
34     {
35         if (b&1) ret = 1ll*ret*a%MO;
36         a = 1ll*a*a%MO, b >>= 1;
37     }
38     return ret;
39 }
40 int main()
41 {
42 //    freopen("ex_t2.in","r",stdin);
44     for (int i=1; i<=m; i++)
45     {
46         C[i][0] = 1;
47         for (int j=1; j<=i; j++)
48             C[i][j] = (C[i-1][j]+C[i-1][j-1])%MO;
49     }
50     for (int i=1; i<=n; i++)
51         a[i] = read(), mxBound += a[i], mnBound = mnBound < a[i]?a[i]:mnBound, s[i] = s[i-1]+a[i];
52     int l = mnBound, r = mxBound, head = 1, tot = 0;
53     for (int mid=(l+r)>>1; l<=r; mid=(l+r)>>1)
54         if (check(mid)) ans = mid, r = mid-1;
55         else l = mid+1;
56     printf("%d\n",ans);
57     for (int i=1; i<=n; i++)
58     {
59         tot += a[i];
60         while (tot > ans) tot -= a[head++];
62     }
63     g[0][0] = f[0][0] = 1, ans = 0;
64     for (int i=1; i<=n; i++)
65     {
66         g[i][0] = 1;
67         for (int j=1; j<=m; j++)
68         {
69             int delta = g[i-1][j-1];
70             if (t[i]>1) delta -= g[t[i]-2][j-1];
71             (f[i][j] += 1ll*delta+MO) %= MO;
72             (g[i][j] = 1ll*g[i-1][j]+1ll*f[i][j]) %= MO;
73         }
74     }
75     for (int i=1; i<=m; i++)
76         ans = (ans+1ll*C[m][i]*f[n][i])%MO;
77     printf("%d\n",ans);
78     return 0;
79 }

 1 #include<bits/stdc++.h>
2 const int maxn = 50003;
3 const int maxm = 1003;
4 const int MO = 10007;
5
6 int n,m,mxBound,mnBound,ans;
7 int a[maxn],s[maxn],t[maxn];
8 short int g[maxn][maxm];
9
11 {
12     char ch = getchar();
13     int num = 0;
14     bool fl = 0;
15     for (; !isdigit(ch); ch = getchar())
16         if (ch=='-') fl = 1;
17     for (; isdigit(ch); ch = getchar())
18         num = (num<<1)+(num<<3)+ch-48;
19     if (fl) num = -num;
20     return num;
21 }
22 bool check(int x)
23 {
24     int cnt = 1, sum = 0;
25     for (int i=1; i<=n; i++)
26         if (sum+a[i] > x) sum = a[i], cnt++;
27         else sum += a[i];
28     return cnt <= m;
29 }
30 int main()
31 {
32 //     freopen("1044.in","r",stdin);
33 //     freopen("1044.out","w",stdout);
35     for (int i=1; i<=n; i++)
36         a[i] = read(), mxBound += a[i], mnBound = mnBound < a[i]?a[i]:mnBound, s[i] = s[i-1]+a[i];
37     int l = mnBound, r = mxBound, head = 1, tot = 0;
38     for (int mid=(l+r)>>1; l<=r; mid=(l+r)>>1)
39         if (check(mid)) ans = mid, r = mid-1;
40         else l = mid+1;
41     printf("%d ",ans);
42     for (int i=1; i<=n; i++)
43     {
44         tot += a[i];
45         while (tot > ans) tot -= a[head++];
47     }
48     register int i,j;
49     ans = 0;
50     for (i=0; i<=n; i++) g[i][0] = 1;
51     for (int i=1; i<=n; i++)
52     {
53         for (int j=1; j<=m; j++)
54         {
55             int delta = g[i-1][j-1];
56             if (t[i]>1) delta -= g[t[i]-2][j-1];
57             (g[i][j] = g[i-1][j]+delta) %= MO;
58         }
59     }
60     for (i=1; i<=m; i++)
61         ans = (ans+g[n][i]-g[n-1][i]+MO)%MO;
62     printf("%d\n",ans);
63     return 0;
64 }

END

posted @ 2018-08-04 12:22  AntiQuality  阅读(215)  评论(0编辑  收藏