洛谷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>=2;--j) 30 if(c1(f[j-1],j-1,j,i)<0) 31 { 32 f[i]=j; 33 goto xx1; 34 } 35 f[i]=1; 36 xx1:; 37 } 38 //printf("2t%d %d %d\n",i,f[0],f[1]); 39 p=f[n]; 40 f[p]=n; 41 for(i=p-1;i>=1&&s[i]=='0';--i) f[i]=n; 42 for(;i>=1;--i) 43 { 44 for(j=p-1;j>=i;--j) 45 if(c1(i,j,j+1,f[j+1])<0) 46 { 47 f[i]=j; 48 break; 49 } 50 } 51 for(i=1;i<=n;i=f[i]+1) 52 { 53 //printf("1t%d\n",f[i]); 54 for(j=i;j<=f[i];++j) 55 putchar(s[j]); 56 if(f[i]!=n) putchar(','); 57 //scanf("%d",new int); 58 } 59 return 0; 60 }