DP 계산 원리

DP 카운트

정수 나누기

양의 정수 nnn 은 여러 양의 정수의 합으로 표현할 수 있으며,이를 양의 정수 n의 나눗셈이라고합니다.

이제 양의 정수 n이 주어지면 n에 대해 얼마나 많은 다른 나눗셈 방법이 있는지 알아보십시오.

완벽한 배낭 쓰기

상태 표현

완전한 배낭 1 ~ i 1 ~ i 와 유사1 ~ i 분为iii 의 각 항목의 볼륨은ii입니다.나는 총 볼륨jj를 찾는 수를 제한하지 않습니다.j에 대한 계획 수

f [i] [j] f [i] [j] f [ i ] [ j ]1에서 i 1에서 i까지를 의미합니다.1 ~ 내가 정확히 전체 볼륨을 선택JJ J

상태 계산

f [i] [j] = f [i − 1] [j] + f [i − 1] [j − i] + f [i − 1] [j − i ∗ 2] + ⋯ + f [i − 1] [j − s ∗ i] f [i] [j] \ qquad = f [i-1] [j] + f [i-1] [j-i] + f [i-1] [j- i * 2] + \ cdots + f [i-1] [j-s * i] f [ i ] [ j ]=f [ i1 ] [ j ]+f [ i1 ] [ ji ]+f [ i1 ] [ j나는2 ]++f [ i1 ] [ j에스i ]

f [i] [j − i] = f [i − 1] [j − i] + f [i − 1] [j − i ∗ 2] + ⋯ + f [i − 1] [j − s ∗ i ] f [i] [j-i] \ \, = \ qquad \ qquad \ quad f [i-1] [j-i] + f [i-1] [j-i * 2] + \ cdots + f [i -1] [j-s * i] f [ i ] [ ji ] =f [ i1 ] [ ji ]+f [ i1 ] [ j나는2 ]++f [ i1 ] [ j에스i ]

∴ \ 그러므로 f [i] [j] = f [i − 1] [j] + f [i] [j − i] f [i] [j] = f [i-1] [j] + f [i] [j-i]f [ i ] [ j ]=f [ i1 ] [ j ]+f [ i ] [ ji ]

하나의 차원으로 최적화

완전한 배낭과 유사하게 작은 것부터 큰 것까지 열거 할 수 있습니다.

f [j] = f [j] + f [j − i] f [j] = f [j] + f [j-i] f [ j ]=f [ j ]+f [ ji ]

const int N = 1010;
int f[N];

int main() {
    
    
	int n;cin >> n;

	f[0] = 1;
	for (int i = 1;i <= n;++i) {
    
    
		for (int j = i;j <= n;++j) {
    
    
			f[j] = (f[j] + f[j - i]) % mod;
		}
	}

	cout << f[n] << endl;
	return 0;
}

또 다른 해결책

상태 표현

모든 합은 ii나는 정확히jj로표현된다j 개 수의 합의 계획

상태 계산

두 가지 상황으로 나뉩니다.

① 최소값은 1이고 1을 제거하여 f [i − 1] [j − 1] f [i-1] [j-1]f [ i1 ] [ j1 ]j − 1 j-1을 의미합니다.제이1 개의 숫자의 합은i − 1 i-1입니다.나는1

② 최소값이 1보다 큽니다. 각 숫자에 1을 빼서 f [i − j] [j] f [i-j] [j] 를 얻습니다 .f [ ij ] [ j ]jj를의미합니다.j 개 수의 합은i − j ij입니다.나는제이

∴ \ 그러므로 f [i] [j] = f [i − 1] [j − 1] + f [i − j] [j] f [i] [j] = f [i-1] [j-1] + f [i-j] [j]f [ i ] [ j ]=f [ i1 ] [ j1 ]+f [ ij ] [ j ]

const int N = 1010;
int f[N][N];

int main() {
    
    
	int n;cin >> n;
	f[0][0] = 1;

	for (int i = 1;i <= n;++i) {
    
    
		for (int j = 1;j <= i;++j) {
    
    
			f[i][j] = (f[i - 1][j - 1] + f[i - j][j]) % mod;
		}
	}
	int res = 0;
	for (int i = 1;i <= n;++i)res = (res + f[n][i]) % mod;

	cout << res << endl;

	return 0;
}

추천

출처blog.csdn.net/zzq0523/article/details/113100669