• spoj-ANARC05H -dp


    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 }
  • 相关阅读:
    visual sudio开发工具使用小技巧
    JS去除右边的逗号
    下拉标题
    sp_addextendedproperty
    触发器的使用
    缺失一个正数
    组合总和 去重
    拖动 Drag
    n皇后问题
    括号生成
  • 原文地址:https://www.cnblogs.com/zzqc/p/8795719.html
Copyright © 2020-2023  润新知