P1043-数字游戏

https://www.luogu.com.cn/problemnew/solution/P1043

研究环状dp

可以开双倍大小的数组用以表示环

表示为  f [ i ] [ j ] [ l ]

从i  到  l 的区间里,划分 l 段

进行递推前,需要初始化  f [ i ] [ j ] [ 1 ]

然后有一个小细节就是sum

进行前缀和优化 将 O(n)的东西优化成 O(1)

可以加快节奏

读取最值时记得扫一遍环  :   f [ i ] [ i+N-1 ]    i : 1 -> N

状态转移方程为   f [ i ] [ j ] [ l ] = min或max( f [ i ] [ j ] [ l ] , f [ i ] [ k ] [ l-1 ] * f [ k-1 ] [ j ] [ 1 ] )    (i <= k < j )

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define py 1e8
 5 #define ll long long
 6 using namespace std;
 7 
 8 inline ll judging(ll a)
 9 {
10     return ((a%10)+10)%10;    
11 }
12 
13 ll sum[10000];
14 ll f[105][105][100];
15 ll f0[105][105][100];
16 
17 int main()
18 {
19     memset(f0,0x7f,sizeof(f0));
20     int n,m;
21     ios_base::sync_with_stdio(false);
22     cout.tie(NULL);
23     cin>>n>>m;
24     for(int i=1;i<=n;i++)
25     {
26          cin>>sum[i];
27          sum[i+n]=sum[i];
28      } 
29     for(int i=1;i<= n * 2; i++)
30     {
31         sum[i]+=sum[i-1];//cout<<sum[]
32     }
33     
34     for(int i=1;i<=2 * n;i++)
35         for(int j=i;j<=2 * n;j++)
36     {
37         f[i][j][1]=judging(sum[j] - sum[i-1]);
38         f0[i][j][1]=judging(sum[j] - sum[i-1]);
39     }
40     for(int l=2;l<=m;l++)
41         for(int i=1;i<=2 * n;i++)
42             for(int j=i+l-1;j<=2 * n;j++)
43             {
44                 for(int k=i+l-2;k<j;k++)
45                 {
46                     f[i][j][l]=max(f[i][j][l],f[i][k][l-1] * f[k+1][j][1]);
47                     f0[i][j][l]=min(f0[i][j][l],f0[i][k][l-1] * f0[k+1][j][1]);
48                 }
49             }
50     ll maxn=0,minn=0x7f;
51     
52     for(int i=1;i<=n;i++)
53     {
54         maxn=max(maxn,f[i][i+n-1][m]);
55         minn=min(minn,f0[i][i+n-1][m]);
56     }
57     cout<<minn<<'\n'<<maxn;
58  } 

嗯……

有一个很讨厌的的地方

就是不要以为  2  *  n  最大是50,就开  f[100] [100] [10]

我就是这样,少开了一位!就一位!)

喜提RE

 

-end-

 

 

posted @ 2020-04-18 16:10  ·Iris  阅读(235)  评论(0编辑  收藏  举报