ANARC05H - Chop Ahoy! Revisited!
Given a non-empty string composed of digits only, we may group these digits into sub-groups (but maintaining their original order) if, for every sub-group but the last one, the sum of the digits in a sub-group is less than or equal to the sum of the digits in the sub-group immediately on its right. Needless to say, each digit will be in exactly one sub-group.
For example, the string 635 can only be grouped in one sub-group [635] or in two sub-groups as follows: [6-35] (since 6 < 8.) Another example is the string 1117 which can be grouped in one sub-group [1117] or as in the following: [1-117], [1-1-17], [1-11-7], [1-1-1-7], [11-17] and [111-7] but not any more, hence the total number of possibilities is 7.
Write a program that computes the total number of possibilities of such groupings for a given string of digits.
Input
Your program will be tested on a number of test cases. Each test case is specified on a separate line. Each line contains a single string no longer than 25, and is made of decimal digits only.
The end of the test cases is identified by a line made of the word "bye" (without the quotes.) Such line is not part of the test cases.
Output
For each test case, write the result using the following format:
k. n
where k is the test case number (starting at 1,) and n is the result of this test case.
Example
Input: 635 1117 9876 bye Output: 1. 2 2. 7 3. 2
f[i][j]表示进行到第i位,且最后一个集合包含j个数字的方案个数,显然f[i][j]=SUM{f[i-j][k] | 只要最后i的最后j个数的和>=i-j的最后k个数的和就能转移}
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define inf 0x3f3f3f3f 4 int main() 5 { 6 char s[30]; 7 int x[30]={0}; 8 int f[30][30]; 9 int i,j,k,cas=0; 10 while(scanf("%s",s+1)){ 11 if(!strcmp(s+1,"bye")) break; 12 int n=strlen(s+1); 13 for(i=1;i<=n;++i){ 14 x[i]=x[i-1]+s[i]-'0'; 15 } 16 memset(f,0,sizeof(f)); 17 f[0][0]=f[1][1]=1; 18 for(i=2;i<=n;++i){ 19 for(j=1;j<=i;++j){ 20 if(i==j) f[i][j]=1; 21 else f[i][j]=0; 22 for(k=1;k<=i-j;++k){ 23 if(x[i]-x[i-j]>=x[i-j]-x[i-j-k]) 24 f[i][j]+=f[i-j][k]; 25 } 26 } 27 } 28 int s=0; 29 for(i=0;i<=n;++i) s+=f[n][i]; 30 cout<<++cas<<". "<<s<<endl; 31 } 32 return 0; 33 }