【JZOJ A組】小凱學數學
阿新 • • 發佈:2018-11-01
Description
由於小凱上次在找零問題上的疑惑,給大家在考場上帶來了很大的麻煩,他決心好好學習數學
本次他挑選了位運算專題進行研究 他發明了一種叫做“小凱運算”的運算子:
a$b =( (a&b) + (a|b) )>>1
他為了練習,寫了n個數在黑板上(記為a[i]) 並對任意相鄰兩個數進行“小凱運算”,把兩數擦去,把結果留下 這樣操作n-1次之後就只剩了1個數,求這個數可能是什麼?
將答案從小到大順序輸出
Input
4
1 4 3 2
Output
1 2
Sample Input
4
1 4 3 2
Sample Output
1 2
Data Constraint
30% n<=10 0<=a[i]<=7
70% n<=150 0<=a[i]<=3
100% n<=150 0<=a[i]<=7
思路
區間DP
設f[i][j][0…7]為區間i…j能否合成0…7
於是列舉斷點,再列舉轉移點即可
程式碼
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int inf=0x3f3f3f3f; int s=0,ss=inf,n; int f[157][157][8]; int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); scanf("%d",&n); for(int i=1; i<=n; i++) { int x; scanf("%d",&x); f[i][i][x]=1; s=max(x,s); ss=min(ss,x); } for(int i=2; i<=n; i++) for(int j=1; j<=n-i+1; j++) { int l=j,r=j+i-1; for(int k=j; k<=j+i-1; k++) { for(int x=ss; x<=s; x++) for(int y=x; y<=s; y++) { f[l][r][(x+y)>>1]|=(f[l][k][x]&f[k+1][r][y])|(f[k+1][r][x]&f[l][k][y]); } } } for(int i=ss; i<=s; i++) if(f[1][n][i]) printf("%d ",i); }