【状压DP】CF 111C,71E,377C,757D,903F,743E,1073E,1316E,327E,906C,1209E2

等有空了再填题解

  • T1:CF111C Petya and Spiders
    • title
    • code
  • T2:CF71E Nuclear Fusion
    • title
  • T3:CF377C Captains Mode
    • title
    • code
  • T4:CF757D Felicity's Big Secret Revealed
    • title
    • code
  • T5:CF903F Clear The Matrix
    • title
    • code
  • T6:CF743E Vladik and cards
    • title
    • code
  • T7:CF1073E Segment Sum
    • title
    • code
  • T8:CF1316E Team Building
    • title
    • code
  • T9:CF327E Axis Walking
    • title
    • code
  • T10:CF906C Party
    • title
    • code
  • T11:CF1209E2 Rotate Columns (hard version)
    • title
    • code

【状压DP】CF 111C,71E,377C,757D,903F,743E,1073E,1316E,327E,906C,1209E2_第1张图片

T1:CF111C Petya and Spiders

title

code

#include 
#include 
using namespace std;
#define inf 0x3f3f3f3f 
int n, m;
int dp[45][300][300];

int get( int x ) {
	int tot = 0;
	for( int i = 1;i <= n;i ++ )
		tot += ( ( x & 1 ) == 0 ), x >>= 1;
	return tot;
}

bool check( int x, int y, int z ) {
	int a, b, c, d, e;
	for( int i = 0;i < n;i ++ ) {
		a = ( 1 << i ) & x;
		b = ( 1 << i ) & y;
		c = ( 1 << i ) & z;
		if( i ) d = ( 1 << ( i - 1 ) ) & y;
		else d = 0;
		if( i < n - 1 ) e = ( 1 << ( i + 1 ) ) & y;
		else e = 0;
		if( a + b + c + d + e == 0 ) return 0; 
	} 
	return 1;
}

int main() {
	scanf( "%d %d", &n, &m );
	if( n > m )	swap( n, m );
	int lim = 1 << n;
	for( int i = 1;i < lim;i ++ )
		for( int j = 0;j < lim;j ++ )
			dp[0][i][j] = -inf;
	for( int p = 1;p <= m;p ++ )
		for( int i = 0;i < lim;i ++ )
			for( int j = 0;j < lim;j ++ )
				for( int k = 0;k < lim;k ++ )
					if( check( i, j, k ) )
						dp[p][j][k] = max( dp[p][j][k], dp[p - 1][i][j] + get( j ) );
	int ans = 0;
	for( int i = 0;i < lim;i ++ )
		ans = max( ans, dp[m][i][0] );
	printf( "%d", ans );
	return 0;
}

T2:CF71E Nuclear Fusion

title

#include 
#include 
#include 
using namespace std;
string mp[105] = { " ", "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", 
"Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", 
"Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb",
"Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba",
"La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
"Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
"Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm" };
vector < int > ans;
int n, k;
bool flag;
int a[20], t[20];
bool vis[105][150000];

int id( string s ) {
	for( int i = 1;i <= 100;i ++ )
		if( mp[i] == s ) return i;
}

void print() {
	int sum = 0, cnt = 0;
	for( int i = 0;i < ans.size();i ++ ) {
		sum += ans[i];
		cout << mp[ans[i]];
		if( sum == t[cnt] ) {
			printf( "->" );
			cout << mp[t[cnt]];
			cnt ++; sum = 0;
			printf( "\n" );
		}
		else printf( "+" );
	}
	exit( 0 );
}

void dfs( int cnt, int sum, int s ) {
	if( sum == t[cnt] ) {
		if( cnt == k ) {
			flag = 1;
			printf( "YES\n" );
			print();
		}
		else dfs( cnt + 1, 0, s );
	}
	if( vis[cnt][s] ) return;
	if( sum > t[cnt] ) return;
	for( int i = 0;i < n && ( ! flag );i ++ ) {
		if( ( 1 << i ) & s ) continue;
		else {
			ans.push_back( a[i] );
			dfs( cnt, sum + a[i], s | ( 1 << i ) );
			ans.pop_back();
		}
	}
	vis[cnt][s] = 1;
}

int main() {
	scanf( "%d %d", &n, &k );
	for( int i = 0;i < n;i ++ ) {
		string ch;
		cin >> ch;
		a[i] = id( ch );
	}
	for( int i = 0;i < k;i ++ ) {
		string ch;
		cin >> ch;
		t[i] = id( ch );
	}
	dfs( 0, 0, 0 );
	printf( "NO" );
	return 0;
}

T3:CF377C Captains Mode

title

code

#include 
#include 
#include 
using namespace std;
#define inf 0x3f3f3f3f
int n, m;
int s[105], t[25], dp[1 << 21];
char opt[25];

bool cmp( int x, int y ) {
	return x > y;
}

int main() {
	scanf( "%d", &n );
	for( int i = 0;i < n;i ++ )
		scanf( "%d", &s[i] );
	sort( s, s + n, cmp );
	scanf( "%d", &m );
	for( int i = 0;i < m;i ++ )
		scanf( "\n%c %d", &opt[i], &t[i] );
	int lim = 1 << m;
	for( int i = 1;i < lim;i ++ ) {
		int j = m - __builtin_popcount( i );
		if( t[j] & 1 ) dp[i] = -inf;
		else dp[i] = inf;
		for( int k = 0;k < m;k ++ )
			if( ( 1 << k ) & i ) {
				int temp = ( opt[j] == 'p' ) ? s[k] : 0;
				if( t[j] & 1 ) dp[i] = max( dp[i], dp[i ^ ( 1 << k )] + temp );
				else dp[i] = min( dp[i], dp[i ^ ( 1 << k )] - temp );
			}
	}
	printf( "%d", dp[lim - 1] );
	return 0;
}

T4:CF757D Felicity’s Big Secret Revealed

title

code

#include 
#define mod 1000000007
const int lim = 1 << 20;
int n, ans;
int a[100];
char s[100];
int dp[100][lim + 10];

int main() {
	scanf( "%d %s", &n, s );
	for( int i = 0;i < n;i ++ )
		a[i] = s[i] - '0';
	for( int i = 0;i < n;i ++ ) {
		dp[i][0] = 1;
		for( int k = 0;k < lim;k ++ ) {
			if( ! dp[i][k] ) continue;
			for( int j = i, tot = a[i];j < n && tot <= 20;j ++, tot = ( tot << 1 ) + a[j] )
				if( tot )
					dp[j + 1][k | ( 1 << ( tot - 1 ) )] = ( dp[j + 1][k | ( 1 << ( tot - 1 ) )] + dp[i][k] ) % mod;
		}
	}
	for( int i = 0;i <= n;i ++ )
		for( int j = 1;j <= 20;j ++ )
			ans = ( ans + dp[i][( 1 << j ) - 1] ) % mod;
	printf( "%d", ans );
	return 0;
}

T5:CF903F Clear The Matrix

title

code

#include 
#include 
#include 
using namespace std;
int n, t, lim = 16;
int w[4], g[1005];
char ch[4][1005];
int num[4][4];
int s[4][4][4];
int dp[1005][16][16][16][16];

int main() {
	scanf( "%d", &n );
	for( int i = 0;i < 4;i ++ )
		scanf( "%d", &w[i] );
	for( int i = 0;i < 4;i ++ )
		scanf( "%s", ch[i] );
	memset( dp, 0x3f, sizeof( dp ) );
	for( int i = 0;i < n;i ++ ) {
		t = 0;
		for( int j = 0;j < 4;j ++ )
			t <<= 1, t += ( ch[j][i] == '.' );
		g[i] = t;
	}
	for( int i = n;i < n + 5;i ++ )
		g[i] = lim - 1;
	dp[0][g[0]][g[1]][g[2]][g[3]] = 0;
	for( int i = 0;i < 4;i ++ )
		for( int j = 0;j < 4 - i;j ++ ) {
			for( int k = 0;k < 4;k ++ )
				for( int p = 0;p < 4;p ++ )
					num[k][p] = 0;
			for( int k = 0;k <= i;k ++ )
				for( int p = j;p <= j + i;p ++ )
					num[k][p] = 1;
			for( int k = 0;k < 4;k ++ ) {
				t = 0;
				for( int p = 0;p < 4;p ++ )
					t <<= 1, t += num[k][p];
				s[i][j][k] = t;
			}
		}
	for( int i = 0;i < n;i ++ )
		for( int a = 0;a < lim;a ++ )
			for( int b = 0;b < lim;b ++ )
				for( int c = 0;c < lim;c ++ )
					for( int d = 0;d < lim;d ++ ) {
						if( dp[i][a][b][c][d] >= 0x3f3f3f3f ) continue;
						if( a == lim - 1 ) dp[i + 1][b][c][d][g[i + 4]] = min( dp[i + 1][b][c][d][g[i + 4]], dp[i][a][b][c][d] );
						for( int j = 0;j < 4;j ++ )
							for( int k = 0;k < 4 - j;k ++ )
								dp[i][a | s[j][k][0]][b | s[j][k][1]][c | s[j][k][2]][d | s[j][k][3]] = min( dp[i][a | s[j][k][0]][b | s[j][k][1]][c | s[j][k][2]][d | s[j][k][3]], dp[i][a][b][c][d] + w[j] );	
					}
	printf( "%d", dp[n - 1][lim - 1][lim - 1][lim - 1][lim - 1] );
	return 0;
}

T6:CF743E Vladik and cards

title

code

#include 
#include 
#include 
using namespace std;
vector < int > g[10];
int n, lim = 1 << 8;
int a[1005], head[10];
int dp[1005][( 1 << 8 ) + 5];

int check( int cnt ) {
	memset( head, 0, sizeof( head ) );
	memset( dp, -1, sizeof( dp ) );
	dp[0][0] = 0;
	for( int i = 0;i < n;i ++ ) {
		for( int j = 0;j < lim;j ++ ) 
			if( dp[i][j] != -1 ) {
				for( int k = 1;k <= 8;k ++ ) {
					if( ( 1 << ( k - 1 ) ) & j ) continue;
					int x = head[k] + cnt - 1;
					if( x >= g[k].size() ) continue;
					dp[g[k][x]][j ^ ( 1 << ( k - 1 ) )] = max( dp[g[k][x]][j ^ ( 1 << ( k - 1 ) )], dp[i][j] );
					++ x;
					if( x >= g[k].size() ) continue;
					dp[g[k][x]][j ^ ( 1 << ( k - 1 ) )] = max( dp[g[k][x]][j ^ ( 1 << ( k - 1 ) )], dp[i][j] + 1 );
				}
			}
		head[a[i]] ++;
	}
	int ans = -1;
	for( int i = 0;i < n;i ++ )
		ans = max( ans, dp[i][lim - 1] );
	if( ans == -1 ) return -1;
	else return ( cnt * 8 + ans );
}

int main() {
	scanf( "%d", &n );
	for( int i = 0;i < n;i ++ )
		scanf( "%d", &a[i] ), g[a[i]].push_back( i );
	int l = 1, r = n >> 3, ans = -1;
	while( l <= r ) {
		int mid = ( l + r ) >> 1;
		if( check( mid ) != -1 ) ans = mid, l = mid + 1;
		else r = mid - 1;
	}
	if( ans == -1 ) {
		ans = 0;
		for( int i = 1;i <= 8;i ++ )
			if( g[i].size() ) ++ ans;
		printf( "%d", ans );
	}
	else printf( "%d", check( ans ) );
	return 0;
}

T7:CF1073E Segment Sum

title

code

#include 
#include 
#define mod 998244353
#define ll long long
ll L, R, ans;
int K;
ll num[20], fac[21], bitcnt[1 << 10];
ll g[20][1 << 10][2][2], f[20][1 << 10][2][2];

void dfs( int pos, int s, bool zero, bool up ) {
	if( ! pos ) {
		g[pos][s][zero][up] = bitcnt[s] <= K;
		f[pos][s][zero][up] = 0;
		return;
	}
	if( ~ g[pos][s][zero][up] ) return;
	g[pos][s][zero][up] = f[pos][s][zero][up] = 0;
	int lim = up ? num[pos] : 9;
	for( int i = 0;i <= lim;i ++ ) {
		int nextS = ( zero & ( i == 0 ) ) ? s : s | ( 1 << i );
		dfs( pos - 1, nextS, zero & ( i == 0 ), up & ( i == lim ) );
		int F = f[pos - 1][nextS][zero & ( i == 0 )][up & ( i == lim )];
		int G = g[pos - 1][nextS][zero & ( i == 0 )][up & ( i == lim )];
		g[pos][s][zero][up] = ( g[pos][s][zero][up] + G ) % mod;
		f[pos][s][zero][up] = ( f[pos][s][zero][up] + 1ll * i * fac[pos - 1] % mod * G % mod + F ) % mod;
	}
}

ll solve( ll x ) {
	memset( f, -1, sizeof( f ) );
	memset( g, -1, sizeof( g ) );
	memset( num, 0, sizeof( num ) );
	int cnt = 0;
	while( x ) num[++ cnt] = x % 10, x /= 10;
	dfs( cnt, 0, 1, 1 );
	return f[cnt][0][1][1];
}

int main() {
	scanf( "%lld %lld %d", &L, &R, &K );
	fac[0] = 1;
	for( int i = 1;i <= 20;i ++ )
		fac[i] = fac[i - 1] * 10 % mod;
	for( int i = 1;i <= ( 1 << 10 );i ++ )
		bitcnt[i] = bitcnt[i >> 1] + ( i & 1 );
	printf( "%lld", ( solve( R ) - solve( L - 1 ) + mod ) % mod );
	return 0;
}

T8:CF1316E Team Building

title

code

#include 
#include 
#include 
using namespace std;
#define ll long long
struct node {
	int a, s[7];
}t[100002];
int n, p, k;
int bitcnt[1 << 7];
ll dp[100002][1 << 7];

bool cmp( node x, node y ) {
	return x.a > y.a;
}

int main() {
	scanf( "%d %d %d", &n, &p, &k );
	for( int i = 1;i <= n;i ++ )
		scanf( "%d", &t[i].a );
	for( int i = 1;i <= n;i ++ )
		for( int j = 0;j < p;j ++ )
			scanf( "%d", &t[i].s[j] );
	sort( t + 1, t + n + 1, cmp );
	int lim = 1 << p;
	for( int i = 1;i < lim;i ++ )
		bitcnt[i] = bitcnt[i >> 1] + ( i & 1 );
	for( int i = 0;i <= n;i ++ )
		for( int j = 0;j < lim;j ++ )
			dp[i][j] = -0x3f3f3f3f;
	dp[0][0] = 0;
	for( int i = 1;i <= n;i ++ )
		for( int s = 0;s < lim;s ++ )
			if( bitcnt[s] <= i ) {
				if( i - bitcnt[s] <= k ) dp[i][s] = max( dp[i][s], dp[i - 1][s] + t[i].a );
				else dp[i][s] = max( dp[i][s], dp[i - 1][s] );
				for( int j = 0;j < p;j ++ )
					if( ( 1 << j ) & s )
						dp[i][s] = max( dp[i][s], dp[i - 1][s ^ ( 1 << j )] + t[i].s[j] );
			}
	printf( "%lld", dp[n][lim - 1] );
	return 0;
}

T9:CF327E Axis Walking

title

code

#include 
#define mod 1000000007
int n, k, x1, x2, ans, t;
int s[1 << 24], dp[1 << 24];

int lowbit( int x ) {
	return x & ( -x );
}

void add( int x ) {
	( ans += x ) >= mod && ( ans -= mod );
}

int main() {
	scanf( "%d", &n ); n = 1 << n;
	for( int i = 1;i < n;i <<= 1 )
		scanf( "%d", &s[i] );
	scanf( "%d", &k ), k && scanf( "%d", &x1 ), k > 1 && scanf( "%d", &x2 );
	dp[0] = 1;
	for( int i = 1;i < n;i ++, ans = 0 ) {
		if( k && ( s[i] = s[i ^ ( t = lowbit( i ) )] + s[t] ) == x1 ) continue;
		if( k > 1 && s[i] == x2 ) continue;
		for( int j = i;j;j ^= t )
			add( dp[i ^ ( t = lowbit( j ) )] );
		dp[i] = ans;
	}
	printf( "%d", dp[n - 1] );
	return 0;
}

T10:CF906C Party

title

code

#include 
#include 
#define inf 0x3f3f3f3f
int n, m;
int p[25];
int dp[1 << 22], fa[1 << 22], g[1 << 22];

void print( int x ) {
	if( fa[x] ) print( fa[x] );
	printf( "%d ", g[x] );
}

int main() {
	memset( dp, 0x3f, sizeof( dp ) );
	scanf( "%d %d", &n, &m );
	for( int i = 1;i <= n;i ++ )
		p[i] = 1 << ( i - 1 );
	for( int i = 1, u, v;i <= m;i ++ ) {
		scanf( "%d %d", &u, &v );
		p[u] |= 1 << ( v - 1 );
		p[v] |= 1 << ( u - 1 );
	}
	if( m == n * ( n - 1 ) / 2 ) return ! printf( "0" );
	for( int i = 1;i <= n;i ++ )
		dp[p[i]] = 1, g[p[i]] = i;
	int lim = 1 << n;
	for( int s = 0;s < lim;s ++ ) {
		if( dp[s] == inf ) continue;
		for( int i = 1;i <= n;i ++ )
			if( ( ( 1 << ( i - 1 ) ) & s ) && dp[s | p[i]] > dp[s] + 1 ) {
				dp[s | p[i]] = dp[s] + 1;
				g[s | p[i]] = i;
				fa[s | p[i]] = s;
			}
	}
	printf( "%d\n", dp[lim - 1] );
	print( lim - 1 );
	return 0;
}

T11:CF1209E2 Rotate Columns (hard version)

title

code

#include 
#include 
#include 
#include 
using namespace std;
struct node {
	int val, id;
	node(){}
	node( int V, int ID ) {
		val = V, id = ID;
	}
}p[2005];
int T, n, m;
int maxx[2005];
int a[15][2005], f[2005][1 << 12], dp[2005][1 << 12];

bool cmp( node x, node y ) {
	return x.val > y.val;
}

int main() {
	scanf( "%d", &T );
	while( T -- ) {
		scanf( "%d %d", &n, &m );
		int lim = 1 << n;
		for( int i = 0;i < m;i ++ )	maxx[i] = 0;
		for( int i = 0;i < m;i ++ )
			for( int j = 0;j < lim;j ++ )
				dp[i][j] = f[i][j] = 0;
		for( int i = 0;i < n;i ++ )
			for( int j = 0;j < m;j ++ )
				scanf( "%d", &a[i][j] );
		for( int j = 0;j < m;j ++ ) {
			for( int i = 0;i < n;i ++ )
				maxx[j] = max( maxx[j], a[i][j] );
			p[j] = node( maxx[j], j );
		}
		sort( p, p + m, cmp );
		m = min( n, m );
		for( int i = 0;i < m;i ++ ) {
			for( int j = 0;j < lim;j ++ )
				for( int k = 0;k < n;k ++ )
					if( ( 1 << k ) & j )
						f[i][j] += a[k][p[i].id];
			for( int j = 0;j < lim;j ++ )
				for( int k = 0;k < n;k ++ ) {
					int t = ( j >> k ) | ( j << ( n - k ) ) & ( lim - 1 );
					f[i][j] = max( f[i][j], f[i][t] );
				}
		}
		for( int i = 0;i < m;i ++ )
			for( int j = 0;j < lim;j ++ ) {
				dp[i + 1][j] = dp[i][j];
				for( int k = j;k;k = ( k - 1 ) & j )
					dp[i + 1][j] = max( dp[i + 1][j], dp[i][j ^ k] + f[i][k] ); 
			}
		printf( "%d\n", dp[m][lim - 1] );
	}
	return 0;
}

你可能感兴趣的:(#,状压DP)