状压dp
Posted caterpillor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状压dp相关的知识,希望对你有一定的参考价值。
P2915 [USACO08NOV]Mixed Up Cows G
dfs去做
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
int b[25],n,m,a[25];
ll cnt;
void dfs(int t, int p){
if(t > n){
cnt++;
return;
}
for( int i = 1; i <= n; i++){
if( !b[i] && abs(a[i] - a[p]) > m){
//cout << i << p << endl;
b[i] = 1;
dfs(t+1, i);
b[i] = 0;
}
}
}
int main(){
scanf ("%d%d", &n, &m);
for(int i = 1 ; i <= n ; i++ )
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++){
memset(b, 0, sizeof b);
b[i] = 1;
dfs(2,i);
}
printf("%lld
", cnt);
return 0;
}
dp[i][j]表示目前有i的人的队列状态,最后站过去的是j编号的人
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
int n , m , a[ 20 ];
ll dp[ (1 << 16 ) + 5 ][ 20 ] ;
int main(){
scanf ( "%d%d" , &n , &m ) ;
for( int i = 1 ; i <= n ; i++ )
scanf ( "%d" , & a[ i ] );
ll sta = ((1 << n) - 1);
//初始化是什么?
for(int i = 1; i <= n; i++)
dp[1 << (i-1)][i] = 1ll;
for(int i = 0; i <= sta; i++)
for(int j = 1; j <= n; j++)
for(int k = 1 ; k <= n; k++){ //均超过k
if((( 1 << (k-1)) | i) == i && (i & (1 << (j - 1))) == 0 && abs(a[k] - a[j]) > m)
dp[i | (1 << (j - 1))][j] += dp[i][k];
}
//答案是什么
long long sum = 0 ;
for( int i = 1; i <= n; i++)
sum += dp[sta][i] ;
printf("%lld
", sum);
return 0;
}
以上是关于状压dp的主要内容,如果未能解决你的问题,请参考以下文章