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 }