等有空了再填题解
- T1:CF111C Petya and Spiders
- T2:CF71E Nuclear Fusion
- T3:CF377C Captains Mode
- T4:CF757D Felicity's Big Secret Revealed
- T5:CF903F Clear The Matrix
- T6:CF743E Vladik and cards
- T7:CF1073E Segment Sum
- T8:CF1316E Team Building
- T9:CF327E Axis Walking
- T10:CF906C Party
- T11:CF1209E2 Rotate Columns (hard version)
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;
}