La programación dinámica, dp

normas de clasificación de dinámicas

  1. Regulación lineal actuador
  2. Reglamento movimiento intervalo
  3. acción reguladora del árbol

Reglamento sección móvil
de acuerdo a las preguntas formuladas, el óptimo global satisfacer óptimo local;

título ejemplo de realización
además de un árbol binario (Los Valley 1040)
titulada Introducción
Descripción sujeto
se proporciona una secuencia de n nodos del recorrido de árbol binario T (1,2,3, ..., n), donde el número 2, 3, ..., n es el número de nodo.
Cada nodo tiene una puntuación (ambos enteros positivos), registrar la puntuación j-ésimo nodo es dj. Conseguir puntos binarios T y cada uno de su subárbol tiene un plus, cualquier subárbol S (incluido el propio T) más iguales izquierda subárbol S de puntos × subárbol derecho de S + S de raíz . Si un sub-árbol está vacío, las disposiciones de su más 1 divididas. Hojas gana puntos extra es el nodo hoja en sí, independientemente de su árbol vacío.
Determinar un orden previo se ajusta a (1,2,3, ..., n) y los puntos más altos de la T. árbol binario T exigió la salida y los puntos más altos de recorrido preorden.
Formato de entrada
Línea 1: un número entero n (n <30), es el número de nodos.
Para la línea 2: n enteros separados por espacios, cada nodo como una fracción (fracción <100).
Formato de salida
Línea 1: un entero, los puntos más altos (resultado no exceden 4000000000).
Línea 2: n enteros separados por espacios, para la preventa de recorrido del árbol.

entrada de la muestra
. 5
. 5. 1. 7 2 10
Salida de muestra

145
3 1 2 4 5

Análisis tema
porque está en el recorrido orden, y por lo tanto nunca se encuentran subárbol izquierdo número de nodo <número de raíz <número de nodo hijo derecho, aunque el árbol, pero la elección y la toma de decisiones no es un problema, y por lo tanto no es un reglas del árbol;
los mejores del mundial al mismo tiempo, cumplir con el rango óptimo, por lo que elegir el intervalo de DP;

ecuación de transferencia dinámica
f [r, l] = max {f [i, k] * f [k, j] + a [i] [i]}

#include<cstdio>
#include<iostream>
using namespace std;
int a[20][20],r[20][20];//r数组存储区间根节点
int n;
void find(int x,int y)//前序遍历,dfs顺序 
{
    if(x<=y)
    {
        printf("%d",&r[x][y]);
        find(x,r[x][y]-1);
        find(r[x][y]+1,y);
    }
    return;
}
int main()//区间dp,局部最优满足全局最优,当前决策具有后效性 
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            a[i][j]=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i][i]);
        r[i][i]=i;
    }
    for(int i=n;i>=1;i--)//a[i][j]枚举的是从i到J的顶点; 
        for(int j=1+i;j<=n;j++)//枚举区间首,尾
            for(int k=i;k<=j;k++)
            {
                if(a[i][j]<a[i][k-1]*a[k+1][j]+a[k][k])//同理,枚举区间i~k-1,k+1~j的最大值,再加上顶点自身值 
                {
                    a[i][j]=a[i][k-1]*a[k+1][j]+a[k][k];
                    r[i][j]=k;//将k定为当前区间根节点 
                }
            }
    printf("%d",a[1][n]);//输出的是从1~n的区间最大值; 
}

Regulación lineal actuador

Un típico casos problemáticos
interceptores de misiles, la formación de coro;

La siguiente es la más larga secuencia ascendente y del ensayo de caída más larga de plantilla

#include<cstdio>
#include<iostream>
using namespace std;
int a[10001],b[10001],c[10001];

int main()
{
    int n=1;
    int maxn=0,mine=0;
    while(scanf("%d",&a[n])){n++;}n--;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)//最长上升
    {
        b[i]=1;
        for(int j=1;j<=i-1;j++)
            if((a[i]>=a[j])&&(b[j]+1>b[i]))b[i]=b[j]+1;
            if(b[i]>maxn)maxn=b[i];
    }
    for(int i=n;i>=1;i--)//最长下降
    {
        c[i]=1;
        for(int j=i+1;j<=n;j++)
        {
            if((a[i]<a[j])&&c[j]+1>c[i])c[i]=c[j]+1;
        }
        if(mine<c[i])mine=c[i];
    }
    printf("%d%d",maxn,mine);
    return 0;
}

Rise secuencia más larga de optimización binaria

#include<cstdio>
#include<iostream>
using namespace std;
int n,top,a[100005],t;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        if(t>a[top])
        a[++top]=t;
        else
        {
            int low=1,high=top,mid;
            while(low<=high)
            {
                mid=(low+high)/2;
                if(a[mid]<t)
                low=mid+1;
                else
                high=mid-1;
            }
            a[low]=t;
        }
}
    printf("%d",top);
}

acción reguladora del árbol

Ningún jefe del partido

Tema Introducción
hay una empresa para celebrar una fiesta.
Con el fin de tener un buen tiempo, líderes de la compañía decidieron: Si invita a alguien, entonces no vamos a invitar a su jefe
(jefe del jefe, el jefe del jefe del jefe ...... puede invitar).

Todo el mundo puede añadir a la atmósfera de fiesta para el número de la persona, la búsqueda de un programa de invitación, y el valor máximo de la atmósfera.

ENTRADA :
Línea 1 número entero N (1 <= N <= 6,000) representados por el número de empresas.
Siguiente N líneas de un número entero. I representa el número de la i-ésimo valor atmósfera personal fila x (-128 <= x <= 127).
A continuación cada fila dos enteros L, K. K representa L personal es el primer supervisor individual.
Ingrese al final de 00.

la salida :
un número, valor máximo y la atmósfera.

entrada:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

salida:
5

Analiza ideas
a esta pregunta se reúnen las características del árbol, que es una acíclico dirigido, pueden tener sucesor múltiples, pero sólo un precursor,
el problema de optimización, el nodo actual seleccionar sólo alrededor de su hijo, se encuentran sin efecto posterior, se puede elegir un árbol dp, por lo tanto, logros, DFS;

#include<iostream>
#include<cstdio> 
using namespace std;
int f[6001][2],father[6001];
bool v[6001];
int n;
int find_max(int a,int b)
{
    if (a>b) return a;
    else return b;
}
void dfs(int k)//f[i][0]储存不选用当前人的最大值,f[i][1]储存选用的最大值 
{
    v[k]=false;
    for (int i=1;i<=n;i++)
        if (v[i] && father[i]==k)
        {
            dfs(i);
            f[k][0]+=f[i][1];
            f[k][1]+=find_max(f[i][0],f[i][1]);
        }
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&f[i][0]);
    int l,k,root;
    root=0;bool bk=true;
    while (scanf("%d%d",&l,&k),l+k>0)
    {
        father[l]=k;
        if (root==l || bk==true)//由于输入的无序性,因此必须找出根节点 
        {
            root=k;bk=false;//根节点等于当前人的上司 
        }
    }
    memset(v,true,sizeof(v));
    dfs(root);//从根节点开始搜索 
    printf("%d\n",find_max(f[root][0],f[root][1]));//输出决策是否选用第一个人(第一个人的数组已储存选与不选的最大值) 
    return 0;
}
Publicado 20 artículos originales · ganado elogios 1 · vistas 6333

Supongo que te gusta

Origin blog.csdn.net/yichengchangan/article/details/60143789
Recomendado
Clasificación