Codeforces 417D.Cunning Gena (状 压 DP)

Enlace al título original La
foto pequeña tiene muchas ganas de participar en la final de la "Copa de cifrado de Rusia", o al menos conseguir una camiseta. Pero el tema de la competencia era demasiado complicado, por lo que discutió con n amigos para ayudarlo a resolver el problema. Hay un total de m preguntas en la competencia. La imagen pequeña conoce los problemas que todo amigo puede resolver. Pero su amigo no le proporcionará ayuda gratuita: el i-ésimo amigo le pide a Xiaotu que pague xi yuanes. Además, se requiere que la computadora de la imagen pequeña esté conectada al menos a monitores ki, y el precio de cada monitor es de b yuanes.

Xiaotu es muy cauteloso con el dinero, por lo que quiere gastar la menor cantidad de dinero posible para resolver todos los problemas. Por favor ayúdeme con un montón de imágenes pequeñas y dígale la cantidad mínima de dinero para resolver todos los problemas. Tenga en cuenta que al principio no hay ningún monitor conectado a la computadora de imagen pequeña.

Ingrese la
primera línea de Ingrese tres números enteros n, m, b (1 ≤ n ≤ 100; 1 ≤ m ≤ 20; 1 ≤ b ≤ 109), que representan respectivamente el número de amigos en la imagen pequeña, el número de preguntas, y el costo de un monitor.

Las siguientes 2n filas de datos ingresados ​​describen los requisitos de estos amigos. Las líneas 2i y (2i + 1) contienen información sobre el i-ésimo amigo. La fila 2i contiene tres números enteros xi, ki y mi (1 ≤ xi ≤ 109; 1 ≤ ki ≤ 109; 1 ≤ mi ≤ m), que representan respectivamente la cantidad de dinero que el amigo quiere, el número de monitores y lo que puede resolver el número de preguntas. La línea (2i + 1) contiene mi diferentes enteros positivos, que representan el número del problema que el i-ésimo amigo puede resolver. Las preguntas están numeradas del 1 al m.

Salida de
imágenes pequeñas para resolver todos los problemas para gastar el menor dinero posible.

Si no hay ningún resultado que cumpla con la condición, envíe -1.

Ejemplos
de entrada
2 2 1
100 1 1
2
100 2 1
1
de salida
202
de entrada
3 2 5
100 1 1
1
100 1 1
2
200 1 2
1 2
de salida
205
de entrada
1 2 1
1 1 1
1
Output
-1

Idea:
el rango de m es muy pequeño, considere usar binario para indicar si un determinado problema está resuelto.
Dp [i] indica el costo mínimo del costo de visualización cuando el estado es i, por lo que solo necesita enumerar los estados de cada amigo puede transferir.
Ordene la cantidad de monitores requeridos por cada amigo, de modo que cuando se enumere la i-ésima persona, el costo del monitor requerido sea fijo.
Ll estalló, para abrirlo.
Código:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
inline ll read()
{
    
    
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a,ll b,ll p)
{
    
    
    ll res=1;
    while(b)
    {
    
    
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
#define PI acos(-1)
#define x first
#define y second
const int maxn=1e6+7,inf=0x3f3f3f3f;
struct node{
    
    
    ull x,k,m;
    ull s;
}a[110];
bool cmp(node a,node b){
    
    
    return a.k<b.k;///排序后枚举到第i个所需的显示器数量就是总的数量
}
ull dp[1<<21];///dp[i]表示当前状态是i时,所需要的最小花费(不计算显示器的花费)
int main()
{
    
    
    int n=read,m=read,b=read;
    for(int i=1;i<=n;i++){
    
    
        cin>>a[i].x>>a[i].k>>a[i].m;
        for(int j=0;j<a[i].m;j++){
    
    
            ull t;cin>>t;
            a[i].s|=1<<t-1;///记录每个人能够解决的问题数
        }
    }
    sort(a+1,a+1+n,cmp);
    dp[0]=0;
    for(int i=1;i<(1<<m);i++) dp[i]=1e19;
    ull res=1e19;
    for(int i=1;i<=n;i++){
    
    
        for(int j=0;j<(1<<m);j++)
            dp[j|a[i].s]=min(dp[j|a[i].s],dp[j]+a[i].x);
        res=min(res,dp[(1<<m)-1]+a[i].k*b);
    }
    if(res==1e19) puts("-1");
    else cout<<res<<endl;
    return 0;
}



Supongo que te gusta

Origin blog.csdn.net/weixin_45675097/article/details/114375944
Recomendado
Clasificación