POJ - 2923 (como una presión mochila dp +)

Tema: Click
significado de las preguntas: cada uno tiene dos vagones de carga, pero cada coche tiene un límite de peso de la carga, preguntar cuántas veces el mínimo de carga todo terminado.

n oscila desde pequeña, pueden considerarse estado de compresión, el principio y no pensó dos coches de diferentes puntos en una situación comprimido, pero ir a DP, se encontró que la complejidad va a explotar, se puede considerar un coche una serie de materiales puede ser transportado, la posible adicionales de escritura a cabo un estado de todas las combinaciones posibles de los estados y los estados resultantes solo se utilizan sólo una vez, publicado un paquete de 01.
dp [i]: el número mínimo necesario para lograr el estado i.

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
const int NUM=1030;
int a[20];
int dp1[1030],dp2[1030];//枚举C1,C2一次能运的状态
int dp[1030];
int sss[1030];
int main()
{
    int T;
    scanf("%d",&T);
    int yy=1;
    while(T--)
    {
        memset(dp,inf,sizeof(dp));
        memset(dp1,-1,sizeof(dp1));
        memset(dp2,-1,sizeof(dp2));
        memset(sss,-1,sizeof(sss));
        int n,i,j,c1,c2,k;
        scanf("%d %d %d",&n,&c1,&c2);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        dp1[0]=dp2[0]=1;
        for(i=1;i<(1<<n);i++)
        {
            int temp=i;
            int sum=0;
            int cnt=0;
            while(temp)
            {
                cnt++;
                if(temp&1)
                {
                    sum+=a[cnt];
                }
                temp>>=1;
            }
            if(sum<=c1)
            {
                dp1[i]=1;
            }
        }
        for(i=1;i<(1<<n);i++)
        {
            int temp=i;
            int sum=0;
            int cnt=0;
            while(temp)
            {
                cnt++;
                if(temp&1)
                {
                    sum+=a[cnt];
                }
                temp>>=1;
            }
            if(sum<=c2)
            {
                dp2[i]=1;
            }
        }
        dp[0]=0;
        for(i=0;i<(1<<n);i++)
        {
            for(j=0;j<=(1<<n);j++)
            {
                if((i&j)==0&&dp1[i]!=-1&&dp2[j]!=-1)
                {
                    sss[i|j]=1;
                }
            }
        }
        for(i=0;i<(1<<n);i++)
        {
            for(j=(1<<n)-1;j>=0;j--)
            {
                if(sss[i]==-1)
                    continue;
                if((j&i)==0)
                dp[i|j]=min(dp[i|j],dp[j]+1);
            }
        }
        printf("Scenario #%d:\n%d\n\n",yy++,min(dp[(1<<n)-1],n));
    }
    return 0;
}

Publicado 72 artículos originales · ganado elogios 19 · vistas 7495

Supongo que te gusta

Origin blog.csdn.net/weixin_43958964/article/details/104993423
Recomendado
Clasificación