jzoj5935小凱學數學

jzoj5935小凱學數學

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][k] 代表 到 的區間是否可能結果爲 k

於是就很顯然了

動態轉移方程:f[i][j][k] = f [i][l][p] | f[r][j][q]

代碼:

#include<cstdio>
#include<cstring>
#define maxx(a,b) a>b?a:b
#define minn(a,b) a<b?a:b
const int mx=150;
int n,ma=0,mi=999999999,x;
bool f[mx+5][mx+5][10];
int main(){
	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	memset(f,0,sizeof(f));
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&x),f[i][i][x]=1;
		ma=maxx(ma,x),mi=minn(mi,x);
	}
	for(int i=2;i<=n;i++)
		for(int j=1;j<=n-i+1;j++){
			int l=j,r=i+j-1;
			for(int k=j;k<=i+j-1;k++)
				for(int x=mi;x<=ma;x++)
					for(int y=x;y<=ma;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=mi;i<=ma;i++)
		if(f[1][n][i])printf("%d ",i);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章