P1043 [NOIP2003 普及组] 数字游戏

原题链接

考察:区间dp

这题就是一维的棋盘分割.

思路:

        f[i][j][k]表示将[i,j]区间分为k份得到的最大值.与棋盘分割不同的是,这道题是一维的,所以我们可以只枚举选上半边就可以枚举到所有方案.也可以枚举选下半边,但是注意这道题要预留足够的空间给进一步选择的上半边和下半边,因为memset初始化后,违法情况会爆数据类型.

        那么棋盘切割为什么不能只枚举上半边呢?因为这里枚举只枚举到r-1处,在第r行仍能纵向切割.所以需要从下往上枚举.

        此外还需要断环成链,枚举每一个长度为n的区间.

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 110,INF = 0x3f3f3f3f;
 6 int m,n,s[N],sum[N],maxn = -INF,minv = INF;
 7 int f[N][N][10],g[N][N][10];
 8 int get(int x)//memset对给定空间填充给定值. 
 9 {
10     return (x%10+10)%10;
11 }
12 void solve()
13 {
14     for(int len=1;len<=n;len++)
15       for(int l=1;l+len-1<=2*n;l++)
16       {
17           int r = l+len-1;
18           for(int k=2;k<=m;k++)
19             for(int t=l;t<r;t++)
20             {
21                if(l+k-2<t)
22                {
23                    int p1 = get(sum[r]-sum[t]);
24                      f[l][r][k] = max(f[l][t][k-1]*p1,f[l][r][k]);
25                      g[l][r][k] = min(g[l][t][k-1]*p1,g[l][r][k]);
26                }
27                if(t+1+k-2<r)
28                {
29                    int p2 = get(sum[t]-sum[l-1]);
30                    f[l][r][k] = max(f[t+1][r][k-1]*p2,f[l][r][k]);
31                    g[l][r][k] = min(g[t+1][r][k-1]*p2,g[t+1][r][k]);
32                }
33           }//如果g[l][r][k] 不够取k份,相乘可能会爆long long(int)
34       }
35 }
36 void init()
37 {
38     memset(f,-1,sizeof f);
39     memset(g,0x3f,sizeof g);
40     for(int len=1;len<=n;len++)
41       for(int l=1;l+len-1<=2*n;l++)
42       {
43           int r = l+len-1;
44           f[l][r][1] = g[l][r][1] = get(sum[r]-sum[l-1]);
45       }
46 }
47 int main() 
48 {
49     scanf("%d%d",&n,&m);
50     for(int i=1;i<=n;i++) scanf("%d",&s[i]),s[i+n] = s[i];
51     for(int i=1;i<=2*n;i++) sum[i] = sum[i-1]+s[i];
52     init(); 
53     solve();
54     for(int i=1;i<=n;i++)
55     {
56         maxn = max(maxn,f[i][i+n-1][m]);
57         minv = min(minv,g[i][i+n-1][m]);
58     }
59     printf("%d\n%d\n",minv,maxn);
60     return 0;
61 }

 

上一篇:十大PHP调试工具


下一篇:springboot核心原理