All X
等比数列求和一下 A/B MOD C = A MOD (B*C) / B 或者分治一下
Sitting in Line
状压+拓扑dp
dp(i, j)表示当前二进制状态为j,当前状态的最后一个数字是a[i],然后按照拓扑序dp进行更新,并用一个bool数组记录是否在队列中。
网上还有其他优美的姿势,按某种枚举方式可以达到拓扑序。
1 #include <bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 int a[20], p[20], n; //输入的第i个数是否固定 5 int vis[20], now[20];//输出的第i个数是否确定 6 ll dp[16][1<<16]; 7 bool isin[16][1<<16]; 8 struct P{ 9 int x, y; 10 P(){} 11 P(int x, int y):x(x), y(y){} 12 }; 13 14 int main(){ 15 int T, ca = 1; 16 cin>>T; 17 while(T--){ 18 memset(vis, 0, sizeof(vis)); 19 cin>>n; 20 for(int i = 0; i < n; i++){ 21 cin>>a[i]>>p[i]; 22 if(p[i] != -1){ 23 vis[ p[i] ] = true; 24 now[ p[i] ] = i; 25 } 26 } 27 28 memset(dp, 0x80, sizeof(dp)); 29 memset(isin, 0, sizeof(isin)); 30 queue<P> Q; 31 if(vis[0]){ 32 dp[ now[0] ][ 1<<now[0] ] = 0; 33 isin[ now[0] ][ 1<<now[0] ] = true; 34 Q.push( P(now[0], 1<<now[0]) ); 35 } 36 else{ 37 for(int i = 0; i < n; i++) 38 if(p[i] == -1){ 39 dp[i][1<<i] = 0; 40 isin[i][1<<i] = true; 41 Q.push( P(i, 1<<i) ); 42 } 43 } 44 45 for(int i = 1; i < n; i++){//pos 46 int size = Q.size(); 47 for(int j = 0; j < size; j++){ 48 P pp = Q.front(); 49 Q.pop(); 50 if(vis[i]){ 51 dp[ now[i] ][ pp.y|(1<<now[i]) ] = max(dp[ now[i] ][ pp.y|(1<<now[i]) ] , dp[pp.x][pp.y]+a[pp.x]*a[ now[i] ]); 52 if(isin[ now[i] ][ pp.y|(1<<now[i]) ] == false) 53 Q.push( P(now[i], pp.y|(1<<now[i])) ), isin[ now[i] ][ pp.y|(1<<now[i]) ] = true; 54 } 55 else{ 56 for(int k = 0; k < n; k++){ 57 if( (pp.y&(1<<k)) == 0&&p[k] == -1){ 58 dp[k][pp.y|(1<<k)] = max(dp[k][pp.y|(1<<k)] , dp[pp.x][pp.y]+a[pp.x]*a[k]); 59 if(isin[ k ][ pp.y|(1<<k) ] == false) 60 Q.push( P(k, pp.y|(1<<k)) ), isin[ k ][ pp.y|(1<<k) ] = true; 61 } 62 } 63 } 64 } 65 } 66 67 ll ans = -1e17; 68 for(int i = 0; i < n; i++) 69 ans = max(ans, dp[i][ (1<<n)-1 ]); 70 printf("Case #%d:\n", ca++); 71 cout<<ans<<endl; 72 } 73 return 0; 74 }
BD String
从某个点断开后,后面的部分折到前面来,刚好和前面部分的后半段拼成一个整体。
1 #include <bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 5 ll getsum(ll x){ 6 if(x <= 2) 7 return x; 8 9 ll fir = 1; 10 while( fir*2 <= x) 11 fir <<= 1; 12 13 return 1LL+x-fir + getsum( fir-(x-fir)-1 ); 14 } 15 int main(){ 16 int t, ca = 1; 17 ll l, r; 18 cin>>t; 19 while(t--){ 20 cin>>l>>r; 21 ll ans = getsum(r)-getsum(l-1); 22 cout<<ans<<endl; 23 } 24 return 0; 25 }
Gym Class
SB拓扑排序即可。
时间: 2024-10-06 16:03:21