#include<stdio.h> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<vector> usingnamespacestd; constint maxn = 1e7+10; longlong A[30], B[30], f[maxn]; intmain(){ int T, rnd=1, n; longlong h; scanf("%d", &T); while(T--){ scanf("%d%lld", &n, &h); for(int i=0; i<n; i++){ scanf("%lld", A+i); } for(int i=0; i<n; i++){ scanf("%lld", B+i); } int up = 1<<n; memset(f, 0, sizeof(f)); for(int i=0; i<up; i++){ longlong sumB = 0; int now = 1; //assume that there are only one guy works per day. //when the bit is 1, A works, then B does not work //get all plans where sumB can reach h for(int j=0; j<n; j++){ if(!(i&now)) sumB += B[j]; now = now<<1; } if(sumB>=h){ f[i]++; } } for(int i=0; i<n; i++){ for(int j=0; j<up; j++){ if(j&(1<<i)){//if A works today f[j] += f[j^(1<<i)]; //plans should add plans where if today does not work //0xor0/1 does not make changes, 1xor1 makes 1 turn to 0 } } } longlong ans = 0; for(int i=0; i<up; i++){ longlong sumA = 0; int now = 1; for(int j=0; j<n; j++){ if(i&now) sumA += A[j]; now = now<<1; } if(sumA>=h){ ans += f[i]; } } printf("Case #%d: %lld\n", rnd++, ans); } return0; }
题意: We have a balance scale and $N$ identical 1-gram marbles numbered from $1$ to $N$. If the difference of the weight between the left pan and the right pan is more than 1, the scale will lose its balance. Now we play a game, we put marbles into the scale in order from $1$ to $N$, each time we put a marble, we can choose whether left or right pan to put into. After we put all marbles into the scale, we start to take them from it: the problem’s input will be a permutation of $\{1,2,…,N\}=\{A_1,A_2,…,A_N\}$, which means the number order of marbles we take out of the scale. Now we need to determine a method to put marbles into the scales(for the number $i$-th marble, choose left or right pan to put). The scale should never lose its balance during the processing above. The permutation of taking out is always legal. $1\leq N\leq 1000$ 分析: Divide this problem into 2 situations: $N$ is odd or even. The easier case is when $N$ is even. When we start to put marbles, we must put a marble on one side then put the next mable on the other side to keep the balance, which means for a odd-numered marble $2i-1$, it must be in a different side of $2i$‘s. For example we can put 1 in left then must put 2 in right. Then we can choose either side to put 3, say right, then we must put 4 in left. Then consider taking out, we can know after putting on, the number of left pan must equal to the right pan’s. So $A_1$ and $A_2$ must in different sides and so do $A_{2i-1}$ and ${A_{2i}}$. 可恶英文写得好麻烦 所以这里面可以得到$N$个对立个关系,我们由此建一张图, 图中的点为石头的编号, 两点连边的则表示两石头不在同一盘子上. 接下来对图染色, 染两个颜色表示放左盘/右盘. 由于题目输入保证合法因此只要遍历一遍图即可染色. 若$N$为基数, 我们知道放石头的时候, 第$N$个放的盘肯定比另一边多一. 取走时, 第一个取走的石子必须从多的那个盘子上取走, 即$N$和$A_1$在同一个盘上. 把这和这两者不在同一盘子内的石子添加到对方边里即可. 剩下的工作和偶数没区别,染色就vans了. 特判一下$N=A_1$的情况, 爱放哪放哪. 这题解写得我好暴躁
题意: There are 4 printer work independently and print “IO,Io,iO,io” respectively. 然鹅四台打印机的结果混在了一起, 像这样: index: 1 2 3 4 5 6 7 8 IO: . . . . . I . O Io: I . . . o . . . iO: . i O . . . . . io: . . . i . . o . string: I i O i o I o O 现在我们拿到的是最终混在一起的打印结果, 需要猜IO这台打印机最多打了多少个IO. 分析: 把四台一起工作的过程看成一个NFA, 不记打印机打了几次的话, 每台打印机要么就是处于打完两个字母(准备打下一个字母)的状态0, 要么就处于打完第一个字母的状态1, 这个nfa就有2^4=16种状态. 一开始四台打印机(IO,Io,iO,io)处在0=0000, 接受一个I时转移到1100=3(左低右高). 在状态转移时再带一个额外的数字k, 记录当前打了多少个IO. 最后由于只有一个终态0000, 把在此状态下的k取最大值即可