Dynamic programming for integer splitting

Source: Internet
Author: User
Enter n, k, and ask how many sharding methods can be used to split n with k numbers ranging from 1 to k. For example, n5 and k3 have n3 + 2, n3 + 1 + 1, n2 + 1 + 1 + 1, n2 + 2 + 1, n1 + 1 + 1 + 1 + 1. This is an obvious dynamic plan. if you cannot think of it as a backpack problem, you can also write the following state transition equation.

Enter n, k, and ask how many sharding methods can be used to split n with k numbers ranging from 1 to k. For example, if n = 5 and k = 3, n = 3 + 2, n = 3 + 1 + 1, n = 2 + 1 + 1 + 1, n = 2 + 2 + 1, n = 1 + 1 + 1 + 1 + 1.

This is an obvious dynamic plan. if you cannot think of it as a backpack problem, you can also write the following state transition equation.

A [I] [j] is used to represent the splicing method of digital I when the number j is used for splicing. the following state transition equation can be obtained: a [I] [j] = a [I] [j-1] + a [I-j] [j-1] + a [i-2j] [j-1] + a [i-3j] [j-1] ]… + A [0] [j-1] means clearly, that is, adding the number of states in which the J-1 state can reach a [I] [j. Because the result may be quite large and has exceeded long, a large number should be used. However, if we run all the data, we can use a large number for more than one second. we can use a large number program and the maximum number is 33 digits. then we can splice two long numbers, A number that consists of more than 33 digits. This increases the speed, and this slow algorithm can not time out.

# Include
 
  
# Include
  
   
Using namespace std; long a [1200] [200] = {0}, B [1200] [120] = {0}; int main () {int I, j, n, m, k; long inf, x; inf = 1; for (I = 0; I <18; I ++) {inf = inf * 10 ;} cin> n> m; for (I = 1; I <= n; I ++) {B [I] [1] = 0; a [I] [1] = 1; for (j = 2; j <= m; j ++) {if (j> I) {a [I] [j] = a [I] [j-1]; B [I] [j] = B [I] [j-1]; continue ;} a [I] [j] = a [I] [j-1]; B [I] [j] = B [I] [j-1]; for (k = 1; k * j <= I; k ++) {if (I-j * k = 0) {a [I] [j] ++; B [I] [j] + = a [I] [j]/inf; a [I] [j] = a [I ] [J] % inf;} else {B [I] [j] + = B [I-j * k] [j-1]; a [I] [j] + = a [I-j * k] [j-1]; B [I] [j] + = a [I] [j]/inf; a [I] [j] = a [I] [j] % inf ;}}} if (B [n] [m]! = 0) {cout <
   
    
In fact, this question is faster, look at the above formula a [I] [j] = a [I] [j-1] + a [I-j] [j-1] + a [i-2j] [j-1] + [i-3j] [j-1]... + A [0] [j-1] we can find that, in fact, there are two states that can be transferred to a [I] [j, one is a [I] [j-1], that is, the number of methods without the number j concatenates the number I, the other is that a [I-j] [j] is the number of I-j methods spliced by the number j. then the state transition equation can be written as a [I] [j] = a [I] [j-1] + a [I-j] [j] do not add so many, this reduces the complexity by an order of magnitude and still uses the above method to process large numbers.
    

#include 
     
      #include 
      
       #include 
       
        using namespace std;long long a[1100][110],b[1100][110],inf;int main(){    int n,k,i,j;    for(inf=1,i=0;i<18;i++) inf*=10;    memset(a,0,sizeof(a));    memset(b,0,sizeof(b));scanf("%d%d",&n,&k);for(i=0;i<=k;i++) a[0][i]=1;    for(i=1;i<=k;i++){        for(j=1;j<=n;j++){            if(j-i<0){b[j][i]=b[j][i-1];a[j][i]=a[j][i-1];continue;}            b[j][i]=b[j][i-1]+b[j-i][i]+(a[j][i-1]+a[j-i][i])/inf;            a[j][i]=(a[j][i-1]+a[j-i][i])%inf;        }    }    if(b[n][k]) printf("%I64d",b[n][k]);    printf("%I64d\n",a[n][k]);    return 0;}
       
      
     

In fact, we can also optimize the space, look at this formula a [I] [j] = a [I] [j-1] + a [I-j] [j] we found that, if the outer circular expression j is actually the last j's value in I and the j's value in I-j, you can open only one-dimensional arrays. the code is as follows:

#include 
     
      #include 
      
       #include 
       
        using namespace std;long long a[1100],b[1100],inf;int main(){    int n,k,i,j;    for(inf=1,i=0;i<18;i++) inf*=10;    scanf("%d%d",&n,&k);    memset(a,0,sizeof(a));    memset(b,0,sizeof(b));    a[0]=1;    for(i=1;i<=k;i++){        for(j=1;j<=n;j++){            if(j-i<0) continue;            b[j]=b[j]+b[j-i]+(a[j]+a[j-i])/inf;            a[j]=(a[j]+a[j-i])%inf;        }    }    if(b[n]) printf("%I64d",b[n]);    printf("%I64d\n",a[n]);    return 0;}
       
      
     

This is actually a complete backpack problem, but the state transfer equation form is different, but the state transfer direction is exactly the same. For (j = 1; j <= k; j ++) for (I = 1; I <= n; I ++) a [I] = a [I] + a [I-j] is the method of this question, because I was from the past, then, the [I-j] above a [I-j] has already considered j, and if it is for (j = 1; j <= k; j ++) for (I = n; I> = 1; I --) a [I] = a [I] + a [I-j]; I is from the back, then a [I-j] does not consider j. it is exactly the case that a can only be used once.

This question is a single group of test data. There are two cases: one is that the question is not clear, the other is actually multiple groups (this case can only be tried), and the other is true single group, however, there are a lot of test data files. In this case, each file runs data once separately. the time that multiple files add up is the time you used for this question. For multiple groups of data, we generally like to create tables. However, for a single set of data, it is the next policy to create a table, because all the tables are typed every time they are run, it is a waste of time. Therefore, you only need to run out the results required by the input data. for the first solution to this question, if you type a table, you can only use TLE. Therefore, you must pay attention to this problem when encountering a real single group.

Note that 64-bit integers can be expressed as _ int64 or long integers, both supported by the compiler, however, for some OJ only supports long, the input and output can be "% I64d" or "% lld". for Mingw and CodeBlocks, only % I64d can be used. However, for some OJ, only % lld can be used, so you must clarify this before the competition. Of course, cin and cout don't need to be considered so much, but it will be relatively slow.

Address of this article: http://www.nowamagic.net/librarys/veda/detail/441,welcome.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.