Subconjunto enumerado
Subconjunto de enumeración binaria El siguiente código es un subconjunto de la enumeración s (compresión de estado binario)
for(int i=s;i;i=(i-1)&s)
{
//i表示的就是s的子集
}
La complejidad temporal de enumerar todos los subconjuntos de subconjuntos. Por
ejemplo, para un conjunto que consta de n elementos, el número de subconjuntos es 2 n 2 ^ n2n , es necesario enumerar todos los subconjuntos de subconjuntos.
Un conjunto que consta de k elementos, el número de subconjuntos es2 k 2 ^ k2k
Considere nnUn subconjunto de n elementos: el
número de elementos es0 0El número de conjuntos de 0 esC n 0 C_n ^ 0Cnorte0
El número de elementos es 1 1El número de conjuntos de 1 esC n 1 C_n ^ 1Cnorte1
… \ Puntos …
Entonces la siguiente ecuación
C n 0 × 2 0 + C n 1 × 2 n +… + C nn × 2 n = (1 + 2) n = 3 n C_n ^ 0 × 2 ^ 0 + C_n ^ 1 × 2 ^ n + \ puntos + C_n ^ n × 2 ^ n = (1 + 2) ^ n = 3 ^ nCnorte0×20+Cnorte1×2norte+⋯+Cnorten×2norte=( 1+2 )norte=3norte
Por lo tanto, finalmente necesitamos enumerar 3 n 3 ^ n3n estados, la complejidad del tiempo esΘ (3 n) \ Theta (3 ^ n)Θ ( 3n )
Cerrar grupo
Primero, preprocese violentamente todos los bloques conectados que cumplan con el significado de la pregunta, y hay bordes directos entre dos puntos en los bloques conectados. Θ (norte 2 + 2 norte) \ Theta (norte ^ 2 + 2 ^ norte)Θ ( n2+2n )
Expresión de estado dp de compresión de estado: fi f_iFyoIndica la opción iii Estos puntos constituyen el número mínimo de
cálculos de estadode grupo: enumeracióniii subconjunto estadojjj, 于是 有fi = min (fi, fj + fi ⊕ j) f_i = min (f_i, f_j + f_ {i \ oplus j})Fyo=m i n ( fyo,Fj+Fi ⊕ j)
Complejidad temporal: enumera un subconjunto de todos los estados, que es la prueba anteriorΘ (3 n) \ Theta (3 ^ n)Θ ( 3n )
Complejidad de tiempo Θ (n 2 + 2 n + 3 n) \ Theta (n ^ 2 + 2 ^ n + 3 ^ n)Θ ( n2+2norte+3n )
3 18 = 387420489 3 ^ {18} = 387420489 31 8=3 8 7 4 2 0 4 8 9 casi puede pasar, lo que hace que la compresión del estado sea tan metafísica
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=20;
bool ok[1<<N];
int g[N][N];
int dp[1<<N];
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
while(m--)
{
int a,b;
cin>>a>>b;
--a,--b;
g[a][b]=g[b][a]=1;
}
for(int i=0;i<1<<n;i++)
{
vector<int> t;
for(int j=0;j<n;j++)
if(i>>j&1) t.push_back(j);
ok[i]=1;
for(int j=0;j<t.size();j++)
for(int k=j+1;k<t.size();k++)
if(!g[t[j]][t[k]]) ok[i]=0;
}
for(int i=0;i<1<<n;i++) dp[i]=n+1;
dp[0]=0;
for(int i=1;i<1<<n;i++)
{
if(ok[i]) dp[i]=1;
for(int j=i;j;j=(j-1)&i)
dp[i]=min(dp[i],dp[j]+dp[j^i]);
}
cout<<dp[(1<<n)-1]<<'\n';
}
return 0;
}
E - O Plus Max
Para un subconjunto de K, yo j ≤ K i \ o \ j \ leq Kyo o r j ≤K
subconjunto enumerado, registrar el valor máximo y el segundo mayor valor del subconjunto, sumarlos
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=500010;
int a[N];
int mx[N],f[N];
int main()
{
IO;
int T=1;
//cin>>T;
for(int ca=1;ca<=T;ca++)
{
int n;
cin>>n;
for(int i=0;i<1<<n;i++)
{
cin>>a[i];
mx[i]=a[0];
}
for(int i=0;i<1<<n;i++)
for(int j=i;j;j=(j-1)&i)
{
f[i]=max(f[i],a[j]+mx[i]);
mx[i]=max(mx[i],a[j]);
}
for(int i=1;i<1<<n;i++)
{
f[i]=max(f[i-1],f[i]);
cout<<f[i]<<'\n';
}
}
return 0;
}