听说标算的点数是2^(n+1)级别的,也不知道我是不是比标算优一点?
(话说这种题一眼看过去怎么跟题答一样)
然而并不是题答,没法手玩,来考虑一下一般解法:
考虑一个规模较小的问题:最后一位一定是0
不难发现变成了条件完全相同的一个子问题
再把最后一位加上
那么总共2^(n-1)个答案中的一部分会翻车,
若把会翻车的部分标记为1,不会翻车的标记为0,又得到一个完全相同的子问题(规模与上一个子问题一样)
那么原问题就可以表示为
(这一位的输入,两个子问题)进行一次操作
没了
考虑复杂度f(x)=2f(x-1)+O(2^x),f(x)=2^x,轻松过
点数应该也差不多是2^n?
1 #include <bits/stdc++.h> 2 #define I n+2 3 #define O n+3 4 using namespace std; 5 int n,N,E,sum; 6 int a[20000],b[20000],c[20000]; 7 bool rule[20000],fir[20000]; 8 void addedge(int x,int y,int z) 9 { 10 a[++E]=x;b[E]=y;c[E]=z; 11 } 12 void work(int st,int en,int len,int pos) 13 { 14 if(len==1) 15 { 16 if((rule[st]&1)&&(rule[en]&1)) addedge(O,n,pos),fir[pos]=1; 17 else 18 if(rule[st]&1) addedge(I,n,pos),fir[pos]=1; 19 else 20 if(rule[en]&1) addedge(I,n,pos),fir[pos]=0; 21 else 22 addedge(O,n,pos),fir[pos]=0; 23 return; 24 } 25 int mid=st+en>>1; 26 work(st,mid,len-1,pos); 27 for(int i=0;i<=mid-st;i++) 28 rule[mid+1+i]^=rule[st+i]; 29 int POS=++N; 30 work(mid+1,en,len-1,POS); 31 addedge(POS,n-len+1,pos); 32 for(int i=0;i<=mid-st;i++) 33 rule[mid+1+i]^=rule[st+i]; 34 } 35 int main() 36 { 37 while(~scanf("%d",&n)) 38 { 39 N=n+3;E=0; 40 fir[I]=1;fir[O]=0; 41 for(int i=1;i<=1<<n;i++) 42 { 43 char ch; 44 for(ch=getchar();!isdigit(ch);ch=getchar()); 45 for(sum=0;isdigit(ch);ch=getchar()) 46 sum=sum*2+ch-'0'; 47 scanf("%d",&rule[sum]); 48 } 49 work(0,(1<<n)-1,n,n+1); 50 printf("%d ",fir[n+1]); 51 printf("%d ",N-n-1); 52 for(int i=n+2;i<=N;i++) 53 printf("%d ",fir[i]); 54 printf("%d ",E); 55 for(int i=1;i<=E;i++) 56 printf("%d %d %d ",a[i],b[i],c[i]); 57 } 58 return 0; 59 }