• hdu1693Eat the trees(插头dp)


    原题网址:http://acm.hdu.edu.cn/showproblem.php?pid=1693

    连通块的表示使用括号表示法。

    1.map

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <map>
     5 
     6 typedef long long LL;
     7 const int MAXRC = 15;
     8 int m,n,er=-1,ec, idx=0;
     9 int city[MAXRC][MAXRC]={0}, bits_at[MAXRC];// 1 is valid.
    10 std::map<LL,LL> mp[2];
    11 
    12 inline int get_state_at(LL s, int j){
    13     return (s&bits_at[j])>>(j<<1);
    14 }
    15 inline LL set_state_at(LL s, int j, int b){
    16     s &= ~(bits_at[j]);
    17     return s|(b<<(j<<1));
    18 }
    19 inline LL set_state_at(LL s, int j, int bj, int bn){
    20     s &= ~(bits_at[j]+bits_at[j+1]);
    21     s |= (bj+(bn<<2))<<(j<<1);
    22     return s;
    23 }
    24 int find_match(LL s, int j){// c!=0
    25     int c = get_state_at(s, j), d = c == 1? 1:-1, f = 0;
    26     for(;;j+=d){
    27         if(get_state_at(s, j)==c) f++;
    28         else if(get_state_at(s,j)) f--;
    29         if(f == 0) return j;
    30     }
    31     return -1;
    32 }
    33 void dp(){
    34     idx = 0;mp[idx].clear();mp[idx][0]=1;
    35     for(int i=0; i<n; ++i){
    36         for(int j=0; j<m; ++j){
    37             int cur = idx^1;// 滚动数组,要求的状态集
    38             mp[cur].clear();
    39             std::map<LL,LL>::iterator it=mp[idx].begin();
    40             for(; it!=mp[idx].end(); ++it){
    41                 LL ps = it->first, pn = it->second;
    42                 if(j == 0) ps <<=2;
    43                 LL sl = get_state_at(ps, j), su = get_state_at(ps, j+1);
    44                 if(sl == 0 && su == 0){
    45                     if(!city[i][j]){// 将状态延伸到无效处
    46                         mp[cur][set_state_at(ps, j, 0, 0)] += pn;
    47                     }// 插头应该指向空白的格子
    48                     else if(city[i][j+1] && city[i+1][j]){
    49                         mp[cur][set_state_at(ps, j, 1, 2)] += pn;
    50                     }
    51                 }
    52                 else if(sl == 0 || su == 0){// 只延伸一个插头
    53                     if(city[i][j+1]) 
    54                         mp[cur][set_state_at(ps, j, 0, sl+su)] += pn;
    55                     if(city[i+1][j])
    56                         mp[cur][set_state_at(ps, j, sl+su, 0)] += pn;
    57                 }
    58                 else if(sl == su){// 合并连通块,同时左括号或右括号
    59                     int posl = find_match(ps, j), posu = find_match(ps, j+1);
    60                     int mn = std::min(posl, posu), mx = std::max(posl, posu);
    61                     LL cs = set_state_at(ps, mn, 1);
    62                     cs = set_state_at(cs, mx, 2);
    63                     mp[cur][set_state_at(cs, j, 0, 0)] += pn;
    64                 }
    65                 else{// 合并成回路
    66                     mp[cur][set_state_at(ps, j, 0, 0)] += pn;
    67                 }
    68             }
    69             idx = cur;// 交换状态
    70         }
    71     }
    72 }
    73 int main(){
    74     freopen("in.txt", "r", stdin);
    75     for(int i=0; i<=14; ++i){
    76         bits_at[i] = 3<<(i<<1);// 0 is invalid, 1 is left bracket, 2 is right bracket.
    77     }
    78     int t, tot;
    79     scanf("%d", &t); tot = t;
    80     while(t--){
    81         scanf("%d%d", &n, &m);
    82         for(int i=0; i<n; ++i){
    83             for(int j=0; j<m; ++j){
    84                 scanf("%d", &city[i][j]);
    85             }
    86         }
    87         dp();
    88         printf("Case %d: There are %lld ways to eat the trees.
    ", tot-t, mp[idx][0]);
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    232.8.flask特殊装饰器
    233.9.flask闪现
    238.14.flask简单项目
    237.13.flask上下文管理
    234.10.flask中间件
    231.7.flasksession
    236.12.flaskthreading.local
    多测师拱墅校区肖sir_高级金牌讲师_selenium实战(3)
    多测师拱墅校区肖sir_高级金牌讲师_rf自动化框架常用的关键字(3)
    多测师拱墅校区肖sir_高级金牌讲师_python 之总结和面试题
  • 原文地址:https://www.cnblogs.com/yyf2016/p/5753431.html
Copyright © 2020-2023  润新知