HDU 6511 - Min-Max(思维+状压)

题意:HDU6511 - 2019中山大学程序设计竞赛

思路:https://blog.csdn.net/jack_jxnu/article/details/89425942

到位了

 1 bool a[1<<16][16];
 2 ll fac[16];
 3 bool b[1001];
 4 int n,m;
 5 struct op{
 6     bool oper,flagx,flagy;//oper表示是否max,flag表示是否数组a、b,
 7     int x,y;
 8 }op[1001];
 9 void pre()
10 {
11     memset(a,0,sizeof(a));
12     int x=1<<n;
13     for(int i=0;i<x;i++)
14         for(int j=1,t=i;j<=n;j++,t>>=1)
15             a[i][j]=t&1;
16 }
17 void getfac()
18 {
19     fac[0]=1;
20     for(int i=1;i<=15;i++)
21     {
22         fac[i]=fac[i-1]*(ll)i;
23     }
24 }
25 bool Find(int i)  //对a[i]数组做模拟运算
26 {
27     for(int j=1;j<=m;j++)
28     {
29         if(op[j].oper)
30         {
31             if(op[j].flagx&&op[j].flagy) b[j]=max(a[i][op[j].x],a[i][op[j].y]);
32             else if(op[j].flagx&&!op[j].flagy) b[j]=max(a[i][op[j].x],b[op[j].y]);
33             else if(!op[j].flagx&&!op[j].flagy) b[j]=max(b[op[j].x],b[op[j].y]);
34             else b[j]=max(b[op[j].x],a[i][op[j].y]);
35         }
36         else
37         {
38             if(op[j].flagx&&op[j].flagy) b[j]=min(a[i][op[j].x],a[i][op[j].y]);
39             else if(op[j].flagx&&!op[j].flagy) b[j]=min(a[i][op[j].x],b[op[j].y]);
40             else if(!op[j].flagx&&!op[j].flagy) b[j]=min(b[op[j].x],b[op[j].y]);
41             else b[j]=min(b[op[j].x],a[i][op[j].y]);
42         }
43     }
44     return b[m];
45 }
46 int getnum(int i)
47 {
48     int ans=0;
49     for(int j=1;j<=n;j++)
50         if(a[i][j]) ans++;
51     return ans;
52 }
53 int main()
54 {
55     string str;
56     char x,y;
57     int p,q;
58     getfac();
59     while(scanf("%d%d",&n,&m)!=EOF)
60     {
61         pre();
62         ll ans=0;
63         for(int i=1;i<=m;i++)
64         {
65             cin>>str>>x>>p>>y>>q;
66             if(str=="max") op[i].oper=1;
67             else op[i].oper=0;
68             if(x=='a') op[i].flagx=1;
69             else op[i].flagx=0;
70             if(y=='a') op[i].flagy=1;
71             else op[i].flagy=0;
72             op[i].x=p;op[i].y=q;
73         }
74         for(int i=0;i<(1<<n);i++)
75         {
76             if(Find(i))
77             {
78                 int cnt=getnum(i);
79                 ans+=fac[cnt]*fac[n-cnt];
80             }
81         }
82         cout<<ans<<endl;
83     }
84     return 0;
85 }

 

posted @ 2020-05-04 10:24  ZMWLxh  阅读(253)  评论(0编辑  收藏  举报