DP #3,4,5 WA求调

P1043 [NOIP2003 普及组] 数字游戏

上面的代码太丑陋了,重贴一份 ```cpp #include<bits/stdc++.h> using namespace std; //f[i][j][k]表示区间[i,j]分成k段的最值 //f[i][j][k]=min/max(f[i][j-l][k-1]*s(j-l+1,j))s(i,j)即[i,j]的区间和 //最终状态min/max(f[i][i+n-1][m]) int n,m,a[55],f1[55][105][15],f2[55][105][15],sum[105]; void init() { for(int i=0;i<=50;i++) for(int j=0;j<=100;j++) for(int k=0;k<=10;k++)f1[i][j][k]=1,f2[i][j][k]=1; for(int i=1;i<=50;i++) { for(int j=i;j-i<50;j++) { f2[i][j][1]=f1[i][j][1]=((sum[j]-sum[i-1])%10+10)%10; } } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; a[n+i]=a[i]; } for(int i=1;i<=2*n;i++)sum[i]=sum[i-1]+a[i]; //for(int i=0;i<=2*n;i++)cout<<sum[i]<<" "; //cout<<endl; init(); for(int len=1;len<n;len++)//枚举区间长度 { for(int i=1;i<=n;i++)//枚举左端点 { int j=i+len;//确定右端点 for(int k=2;k<=len+1;k++)//枚举分段数 { f1[i][j][k]=0x3f3f3f3f; for(int l=1;len+1-l>=k-1;l++)//枚举断点 { f1[i][j][k]=min(f1[i][j][k],f1[i][j-l][k-1]*(((sum[j]-sum[j-l])%10+10)%10)); f2[i][j][k]=max(f2[i][j][k],f2[i][j-l][k-1]*(((sum[j]-sum[j-l])%10+10)%10)); //cout<<f1[i][j][k]<<" "<<i<<" "<<j<<" "<<k<<" "<<l<<endl; } } } } int ans1=0x3f3f3f3f,ans2=0; for(int i=1;i<=n;i++) { int j=i+n-1; ans1=min(ans1,f1[i][j][m]); // cout<<i<<" "<<j<<" "<<f1[i][j][m]<<endl; ans2=max(ans2,f2[i][j][m]); } cout<<ans1<<endl<<ans2; return 0; } ```
by xiaoxiao090104 @ 2023-08-08 21:14:49


qp
by Do_chen @ 2023-08-09 08:19:31


@[Do_chen](/user/734748) 大佬给我支个招
by xiaoxiao090104 @ 2023-08-09 18:31:00


你将数组拆成两倍没有问题,但是你之后用来访问的变量也应该到 $2n$,再就是我觉得 DP 时的变量 `j` 应赋值为 `i + len - 1` 而不是 `i + len`。我也只是猜测,如果不对请纠正。
by DeltaCR @ 2023-10-13 17:42:01


|