洛谷P1415 拆分数列

https://www.luogu.org/problemnew/show/P1415

不会。。

看洛谷题解吧。。

自己的理解:标程做法是:先做一遍dp求出最后一个数开始位置的最大值p,那么就相当于最后一个逗号必须加在p位置左侧;然后反着dp一遍,求出dp[i]表示T(i,n)划分结果中使得第一个数最大时第一个数最大的结束位置(dp[p]=n,dp[p前面连续一段0]=n(否则这一小段0会给出有问题的答案;这么做是没有问题的,因为如果p前面全部是0那么可以发现没有问题,p前面还有非0那么不可能这些0单独成一段;再前面就不用特判了,因为一定存在<p的答案),且结束位置有边界<p);最后一步贪心确定答案,每一次都取当前能取的最大数

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define fi first
 7 #define se second
 8 #define mp make_pair
 9 #define pb push_back
10 typedef long long ll;
11 typedef unsigned long long ull;
12 typedef pair<int,int> pii;
13 char s[510];
14 int n;
15 int c1(int l1,int r1,int l2,int r2)
16 {
17     for(;l1<=r1&&s[l1]=='0';++l1);
18     for(;l2<=r2&&s[l2]=='0';++l2);
19     if(r1-l1!=r2-l2)    return r1-l1<r2-l2?-1:1;
20     else    return strncmp(s+l1,s+l2,r1-l1+1);
21 }
22 int f[510];
23 int main()
24 {
25     int i,j,p;
26     scanf("%s",s+1);n=strlen(s+1);
27     for(i=1;i<=n;++i)
28     {
29         for(j=i;j>=1;--j)
30             if(c1(f[j-1],j-1,j,i)<0)
31             {
32                 f[i]=j;
33                 break;
34             }
35     }
36     p=f[n];
37     f[p]=n;
38     for(i=p-1;i>=1&&s[i]=='0';--i)    f[i]=n;
39     for(;i>=1;--i)
40     {
41         for(j=p-1;j>=i;--j)
42             if(c1(i,j,j+1,f[j+1])<0)
43             {
44                 f[i]=j;
45                 break;
46             }
47     }
48     for(i=1;i<=n;i=f[i]+1)
49     {
50         for(j=i;j<=f[i];++j)
51             putchar(s[j]);
52         if(f[i]!=n)    putchar(',');
53     }
54     return 0;
55 }
View Code

猜你喜欢

转载自www.cnblogs.com/hehe54321/p/9919142.html