AcWing-900.Целочисленное деление (java реализация)

AcWing-900 Целочисленное деление

описание темы

Натуральное число n может быть представлено в виде суммы нескольких положительных целых чисел, например: n=n1+n2+…+nk, где n1≥n2≥…≥nk, k≥1.

Мы называем такое представление делением натурального числа n.

Теперь, учитывая положительное целое число n, выясните, сколько различных способов деления существует для n.

формат ввода

Всего одна строка, содержащая целое число n.

Выходной формат

Всего одна строка, содержащая целое число, обозначающее общее количество делений.

Поскольку ответ может быть очень большим, пожалуйста, возьмите по модулю 10 ^ 9 + 7 для выходного результата.

диапазон данных

1≤n≤1000

Входной образец:

5

Пример вывода:

7

Идеи (простая версия)

Представление состояния: f ( i , j ) означает выбор всех методов из 1 i , которые можно просто преобразовать в j Представление состояния: f(i, j) означает выбор всех методов из 1~i, которые можно просто преобразовать в jГосударственное представительство : f ( i ,ж ) ,Указывает на все методы , которые могут быть написаны j от 1 i 

Атрибут: Количество Атрибут: КоличествоАтрибут : Количество

Ядро: Последнее число i не берется, или берется k штук, чтобы сформировать j Ядро: последнее число i не берется, или берется k штук, чтобы сформировать jядро:Не берите последнее число i и не берите k чисел и записывайте его как j.

Деление состояний: f ( i − 1 , j ) принимает 0 i, 1 i ... ..., k i становится f ( i , j ) делением состояний: f (i-1, j) принимает 0 i, 1 i. ..,k i становится f(i,j)государственное деление:ж ( я1 ,к ) взять 0 я , _1 я _,k я становлюсь ж ( я , _ж )

Уравнение перехода состояний может быть получено делением состояний:
f (i, j) = f (i-1, j) + f (i-1, j-i) + f (i-1, j-2i) + … … + f ( i − 1 , j − ki ) f(i,j) = f(i-1,j)+f(i-1,ji)+f(i-1,j-2i)+… + f(i-1,j-ки)ф ( я ,ж )"="ж ( я1 ,ж )+ж ( я1 ,Джя )+ж ( я1 ,Дж) _++ж ( я1 ,Джк я )

ж ( я , j - я ) знак равно ж ( я - 1 , j - я ) + ж ( я - 1 , j - 2 я ) + … … + ж ( я - 1 , j - ki ) f (i, ji ) = ~~~~~~~~~~~~~~~f(i-1,ji)+f(i-1,j-2i)+……+f(i-1,j-ki)ф ( я ,Джя )"="               ж ( я1 ,Джя )+ж ( я1 ,Дж) _++ж ( я1 ,Джк я )

Вычтите конечное уравнение перехода состояния
: джи)ф ( я ,ж )"="ж ( я1 ,ж )+ф ( я ,Джя )

основной код

		for(int i=1;i<=n;i++) {
    
    
			for(int j=0;j<=n;j++) {
    
    
	            dp[i][j] = dp[i - 1][j] % MOD; //	如果容量j小于i的话,不能对i进行选择。
	            if (j >= i) {
    
    	//只有容量j大于等于i时,才能对i的选择多少进行讨论
					dp[i][j] = (dp[i-1][j]+dp[i][j-i]) % MOD;
	            }
			}
		}

полный код

package acWing900;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
    
    
	static int N = 1010,MOD = (int) (1e9+7);
	static int n;
	static int dp[][] = new int[N][N];
	public static void main(String[] args) throws Exception{
    
    
		Read r = new Read();
		n = r.nextInt();
		for(int i=1;i<=n;i++) {
    
    
			dp[0][i] = 0;	//	当容量为i有0个物品一个则没有方案。
		}
		for(int i=0;i<=n;i++) {
    
    
			dp[i][0] = 1;	//	当容量为0前i个物品一个不选也是一种方案。
		}
		// 特殊 dp[0][0] = 1
		for(int i=1;i<=n;i++) {
    
    
			for(int j=0;j<=n;j++) {
    
    
	            dp[i][j] = dp[i - 1][j] % MOD; //	如果容量j小于i的话,不能对i进行选择。
	            if (j >= i) {
    
    	//只有容量j大于等于i时,才能对i的选择多少进行讨论
					dp[i][j] = (dp[i-1][j]+dp[i][j-i]) % MOD;
	            }

			}
		}
		System.out.println(dp[n][n]);
	}
class Read{
    
    
	StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	public int nextInt() throws Exception{
    
    
		st.nextToken();
		return (int)st.nval;
	}
}

Уменьшение размерности (с использованием скользящих массивов)

Комбинированное уравнение перехода в конечное состояние
: я, джи)ф ( я ,ж )"="ж ( я1 ,ж )+ф ( я ,Джi )
В соответствии с уравнением состояния необходимо использовать только текущую строку и предыдущую строку, поэтому можно использовать концепцию скользящего массива для сведения двумерного изображения к одномерному, а именно: f ( j ) = f
( j ) + f ( j − i ) f (j) = f (j) + f (ji)ж ( дж )"="ж ( дж )+ж ( йя )

Основной код:

		for(int i=1;i<=n;i++) {
    
    
			for(int j=i;j<=n;j++) {
    
    
				dp[j] = (dp[j]+dp[j-i]) % MOD;
			}
		}

Полный код:

package acWing900;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
    
    
	static int N = 1010,MOD = (int) (1e9+7);
	static int n;
	static int dp[] = new int[N];
	public static void main(String[] args) throws Exception{
    
    
		Read r = new Read();
		n = r.nextInt();
		dp[0] = 1;
		for(int i=1;i<=n;i++) {
    
    
			for(int j=i;j<=n;j++) {
    
    
				dp[j] = (dp[j]+dp[j-i]) % MOD;
			}
		}
		System.out.println(dp[n]);
	}
}
class Read{
    
    
	StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	public int nextInt() throws Exception{
    
    
		st.nextToken();
		return (int)st.nval;
	}
}

Supongo que te gusta

Origin blog.csdn.net/gudada010/article/details/117483802
Recomendado
Clasificación