문제 해결: DP(정수 분할 문제)
입력 표준의 입력은 몇 개의 테스트 데이터를 포함한다.각 그룹의 테스트 데이터는 두 개의 정수 N과 K를 포함하는 한 줄의 입력 데이터이다.(0 < N <= 50, 0 < K <= N)
출력은 각 그룹의 테스트 데이터에 대해 다음과 같은 세 줄의 데이터를 출력한다. 첫 번째 줄: N은 K개의 정수의 합으로 나누는 두 번째 줄: N은 몇 개의 정수의 합으로 나누는 세 번째 줄: N은 몇 개의 서로 다른 정수의 합으로 나누는 네 번째 줄: N은 몇 개의 기정수의 합으로 나누는 세 번째 줄로 나뉜다.
샘플 입력 5 2
샘플 출력 2 7 3 3
분석하다.
n을 약간의 정정수의 합으로 나누는 구분수를 구하다
둘째, n을 k개의 정수로 나누는 구분수는 dp[i][j]를 j개의 정수로 나누는 구분수로 한다.(1) i
p[n][k]는 n을 k개의 정수로 나누는 구분수로 문제를 해결할 수 있다.
n을 약간의 정기수의 합으로 나누는 구분수
f[i][j]를 j개의 홀수의 합으로 나누는 구분수로 설정하고, g[i][j]는 i를 j개의 짝수의 합으로 나누는 구분수로 한다.
절단법을 사용하여 g[i][j]의 j개 구분을 모두 1로 나누면 f[i-j][j]를 얻을 수 있기 때문에
g[i][j] = f[i-j][j].
f[i][j]에는 1을 포함하는 구분 방안과 1을 포함하지 않는 구분 방안이 있다.
1을 포함하는 구분 방안에 대해 1의 구분을 제외하고'i-1을 j-1의 홀수의 합으로 나누는 구분수', 즉 f[i-1][j-1]로 전환할 수 있다.1이 포함되지 않는 구분 방안에 대해 절단법으로 j개의 구분을 하나하나 1을 제거하고'i-j를 j개의 짝수의 합으로 나누는 구분수', 즉 g[i-j][j]로 전환할 수 있다.
그래서 f[i][j]=f[i-1][j-1]+g[i-j][j].
f[n][0]+f[n][1]+...+f[n][n]는 n을 약간의 홀수로 나누는 구분수로 문제 4의 답안이다.
계속해서 코드에 주석이 있습니다
#include
#include
#include
#define maxn 55
using namespace std;
int num[maxn][maxn];//i k
int num2[maxn][maxn];//
int f[maxn][maxn];//
int g[maxn][maxn];
void init()
{
int i, j;
for (int i = 1; i < maxn; i++)
num[i][0] = num[0][i] = num2[i][0] = num2[0][i] = 0;
for (int i = 1; i < maxn; i++)
{
for(int j = 1; j < maxn; j++)
{
if (i < j)
num[i][j] = 0;
else if (i == j)
num[i][j] = 1;
else// 1
num[i][j] = num[i - 1][j - 1] + num[i - j][j];
}
}
f[0][0] = 1, g[0][0] = 1;
for (i = 1; i < maxn; i++)
{
for (j = 1; j <= i; j++)
{
g[i][j] = f[i - j][j];
f[i][j] = f[i - 1][j - 1] + g[i - j][j];
}
}
}
long long fun2(int n, int m)// n , m
{
if (n == 1 || m == 1)
return 1;
else if (n < m)
return fun2(n, n);
else if (n == m)
return (1 + fun2(n, m - 1));
else
return (fun2(n, m - 1) + fun2(n - m, m));
}
int fun(int n, int m)// n , m
{
if (n == 1 && m == 1)
return 1;
else if (m == 1)
return 0;
else if (n < m)
return fun(n, n);
else if (n == m)
return (1 + fun(n, m - 1));
else
return (fun(n, m - 1) + fun(n - m, m - 1));
}
int main(void)
{
init();
int n, m, res;
while (scanf("%d %d", &n, &m) != EOF)
{
printf("%d
", num[n][m]);
printf("%d
", fun(n, n));
printf("%lld
", fun2(n, n));
res = 0;
for (int i = 1; i <= n; i++)
res += f[n][i];
printf("%d
", res);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[BOJ]11048(python)python 풀이 DP를 이용해 풀이 보통 이런 문제는 dfs나 bfs로 풀이하는 것이여서 고민을 했는데 이 문구 덕분에 DP 를 이용해 풀이할 수 있었다 뒤로 돌아가는 등의 경우를 고려하지 않아도 되기 때문이다 코...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.