algoritmo dp - poj 4119: problema de divisão inteira complexa

título

prazo total: 200ms limite de memória: 65536kB
descreve
um inteiro positivo e n representa uma série de inteiros positivos e, n = n1 + n2 + ... + nk, onde n1> = n2> = ...> = nk> = 1, k> = 1 .
Isto representa um número inteiro positivo n é um número inteiro positivo n é chamado de particionamento.

Entrada
entrada padrão compreendendo uma pluralidade de conjuntos de dados de teste. Cada teste é uma linha de dados de entrada, que compreende dois inteiros N e K.
(0 <N <= 50, 0 <K <= N)
de saída
, para cada teste, os seguintes três linhas de saída de dados:
primeira linha: N é dividido em um certo número de números inteiros positivos K e a
segunda linha: N divisão o número é dividido em vários números inteiros positivos diferentes e a
terceira linha: N é dividido em um número ímpar e o número de divisão de inteiros positivos
amostra de entrada
52
de amostra de saída
2
3.
3.
Tip
primeira linha: 4 + 1, 3 + 2,
segunda linha: 5,4 + 1,3 + 2
linha 3: 1 + 5,1 + 3, 1 + 1 + 1 + 1 + 1 + 1

primeiro pediu

O problema inteiro particionamento do que o problema antes de uma restrição de K, este problema pode ser comparada ao problema da mochila, o problema é convertido para o seguinte:
seleccionar o número K [1 ... N], e o qual é N, e é seleccionado a partir de o número pode ser repetido, o que é um típico problema de programação dinâmica.
Considere então as sub-problemas, a partir de [i ... 1] seleccionado número q, e que é J.
Pedido f [i] [j] [ q] Soluções subproblems FIG.
Considere as seguintes condições de contorno: seleccionar um número a partir de um [1 ... 1], o qual é 1, o único método seleccionado a partir do grupo F [1] [1] [ 1] = 1;
próxima considerar uma transição de estado:
F [I] [J] [Q] = F [. i-1] [J] [Q] + F [i] [J - i] [Q -. 1]
[. i-1] F [J] [Q] indica o th i o número não for seleccionada, então para seleccionar o número q da anterior i-1, e que é J
F [i] [J - i] [Q-1] indica o i-ésimo seleccionado, em seguida, a frente seleccionado número i q-1 um, e que é JI, onde i é não i-1 é feita, porque em questão vai ser utilizado na sub-i, isto é, cada número seleccionado não é único,
é um caso especial do problema geral da mochila.
Desta forma, a solução desta questão através de um grupo de três dígitos para gravar processo de planejamento dinâmico pode ser, mas alguns planejamento é matrizes dinâmicas podem ser usados para rolagem para economizar espaço, este caminho pode ser.
Suponha-se que um grupo de dois dígitos f [j] [q], com uma camada de ciclo anterior i representa o número de seleccionado, antes do primeiro ciclo foi iniciado i, f [j] [Q] representa o número de i-1 frente seleccionado fazer-se o q j, para f [i] [ji] [ Q-1]
, porque transversal antes f [i] [j] [ Q] a, o f [ji] valor [q-1] em é o i-ésimo valor do ciclo actualizado, de modo que a transição de estado pode ser simplificado para:
F [J] [Q] + = F [JI] [-Q 1.]
esta parte do código como se segue:

dp[0][0] = 1;
for (int i = 1; i <= n; i++)
    for (int j = i; j <= n; j++)
	for (int q = k; q >= 1; q--)
	    dp[j][q] += dp[j - i][q - 1];
printf("%d\n", dp[n][k]);

A segunda questão

A segunda questão antes de um aumento do problema de divisão de número inteiro digital simples que não pode ser repetido limite, o que se reflecte na equação de transição de estado está no interior:
conjunto f [i] [j] indica o número de hash i anterior j,
a equação de transição de estado:
F [i] [j] = f [i-1] [ji] + f [i-1] [j]
da mesma forma, bidimensional matriz pode ser deslocado para uma dimensão de notar que j no descendente transversal
do código:

dp1[0] = 1;
        for (int i = 1; i <= n; i++)
            for (int j = n; j >= i; j--)
                dp1[j] += dp1[j - i];
        printf("%d\n", dp1[n]);

terceira pergunta

Após a terceira questão do que um simples aumento problema divisão inteira só pode escolher um número ímpar positivo, nota, digital estática repetido, compreender este fato, as duas primeiras questões é muito bom para escrever
directamente para escrever a equação de transição de estado:
f [ I] [J] = F [I] [J - I] + F [I-2] [J]
... F [1] [1] = 1
pelo material da matriz, então, i tomar travessia estranho, j necessária desde pequenas a grandes para travessia .
código:

dp2[0] = 1;
        for (int i = 1; i <= n; i += 2)
            for (int j = i; j <= n; j++)
                dp2[j] += dp2[j - i];
        printf("%d\n", dp2[n]);

Código perguntas inteiras:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

typedef long long ll;

const int N = 50 + 5;
int dp[N][N], dp1[N], dp2[N];

int main() {
    for (int n, k; scanf("%d%d", &n, &k) == 2;) {
        memset(dp, 0, sizeof(dp));
        memset(dp1, 0, sizeof(dp1));
        memset(dp2, 0, sizeof(dp2));
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++)
            for (int j = i; j <= n; j++)
                for (int q = k; q >= 1; q--)
                    dp[j][q] += dp[j - i][q - 1];
        printf("%d\n", dp[n][k]);
        dp1[0] = 1;
        for (int i = 1; i <= n; i++)
            for (int j = n; j >= i; j--)
                dp1[j] += dp1[j - i];
        printf("%d\n", dp1[n]);
        dp2[0] = 1;
        for (int i = 1; i <= n; i += 2)
            for (int j = i; j <= n; j++)
                dp2[j] += dp2[j - i];
        printf("%d\n", dp2[n]);
    }
    return 0;
}

Código de referência: https://blog.csdn.net/Nightmare_ak/article/details/94414363

Acho que você gosta

Origin www.cnblogs.com/zhangyue123/p/12557503.html
Recomendado
Clasificación