Programming Contest challenges: the number of divisions

Subject to the effect

Here Insert Picture Description

Problem-solving ideas

Such problems are generally referred to as n n the m m division. Note that this is classified asless than m equalparts, the use of dynamic programming solution.

  • definition: d p [ i ] [ j ] dp[i][j] : j j 's i i total number of splits.
  • Target state: d p [ m ] [ n ] dp[m][n] .
  • State transition:
    • Wrong idea: that the demand j j 's i i When the division, from j j in Naqu k k a, then seek j k j-k 's i 1 i-1 division, that is,
      d p [ i ] [ j ] = k = 1 j 1 d p [ i 1 ] [ j k ] dp[i][j] = \sum_{k=1}^{j-1}dp[i-1][j-k]
    • Error point: will { 1 , 1 , 2 } \{1,1,2 \} and { 1 , 2 , 1 } \{1,2,1\} considered as different divisions.
    • The right idea: for j j 's i i division, there are two cases: (1) In order to exactly divide i i parts. (2): For less than partitioning i i parts.
      • In the first case: We want to take away from every which are a result of the original and the result is one to one. Therefore, a total of d p [ i ] [ j i ] dp[i][j-i]
      • Second case: direct correspondence is d p [ i 1 ] [ j ] dp[i-1][j] . Thus eventually
        d p [ i ] [ j ] = d p [ i 1 ] [ j ] + d p [ i ] [ j i ] dp[i][j] = dp[i-1][j]+dp[i][j-i]
  • Update Policy: d p [ i ] [ j ] dp[i][j] dependent on the left of and above d p [ i ] [ j ] dp[i'][j'] , According to line by line so the update cycle.
  • Initial state: d p [ 0 ] [ ] = 0 , d p [ 0 ] [ 0 ] = 1 dp[0][*] = 0, dp[0][0] = 1 : i.e., when no article is divided into only a method that 0 parts.
  • Note: In the transfer process, there will be d p [ 2 ] [ 0 ] = 1 dp[2][0] = 1 such a situation, such as if it is not realistic, because he represents 0 0 2-division two items actually there is a. This is because we have takentake the equivalentof strategy, this status will only be d p [ 2 ] [ 2 ] dp[2][2] cited. Therefore must 1 1 without affecting other values.
  • the complexity: O ( m n ) O (mn)

Code

#include<iostream>
using namespace std;
const int MAX = 1005;
int dp[2][MAX];
int main()
{
    int m, n;
    cin >> n >> m;
    int M;
    cin >> M;
    dp[0][0] = 1;
    for(int i=1; i<=m; i++)
    {
        for(int j=0; j<=n; j++)
        {
            if(j-1 >= 0)
                dp[i%2][j] = (dp[1-i%2][j] + dp[i%2][j-i]) % M; 
            else
                dp[i%2][j] = dp[1-i%2][j];// 当总数j小于划分数i时,不可能每一份都大于0
        }
    }
    cout << dp[m%2][n] << endl;
}

Guess you like

Origin blog.csdn.net/Wangpeiyi9979/article/details/93591187