zoukankan      html  css  js  c++  java
  • POJ 搜索(2)

    最优化剪枝和可行性剪枝

    poj1699

    搜索的技巧和优化

    poj3411, poj1724

    记忆化搜索

    poj3373,poj1691

    最优化剪枝和可行性剪枝

    POJ 1699

    对这题无语了,爆搞TLE,加一个怎么也没想到的减枝47MS...

    规模并不大,可以直接dfs,需要预处理一下,add[i][j]表示第j号串加在第i号串上增加的长度。。。这个计算的时候要注意。本菜就错在这上边wa了一上午!。

    搜索的技巧和优化 

    poj 3411

    题意:有m条路,N个顶点。从ai到bi的路要付费,付费有两种方式:1、比如之前去过ci,则可以在ci预付pi的费用。2、到达bi以后再付费,这样的费用是ri。求从1到N共的最小付费是多少。

    题解:这题的规模不大,可以直接爆搞。但是,每条边的访问次数可以是多次。也就是说每个顶点可以访问多次,这样的话可以类似spfa的方法记录每一顶点的访问次数,当超过n次时conintue;当然还可以像POJ 1699一样加一个剪枝。cost记录dfs到当前的花费,如果cost >= ans则可以直接return;

    poj 1724

    题意:Bob要离家出走,从1号城市去N号城市。Bob手头有k money,每过一条路需要叫一点数目的money,否则不能通过,求在k money的承受范围内的最短路。

    题解:话说3411时我想的一个错误的方法在这里居然可行,哈哈 ^_^。cat[u][v]表示u到v的边数。这样可以判出有环无环的情况,然后dfs。

    View Code
    void dfs(int u, int l, int k) {
        if(l >= ans)    return ;
        if(u == n) {
            ans = Min(ans, l);
            return ;
        }
        int v, i;
        for(i = head[u]; i != -1; i = g[i].next) {
            v = g[i].to;
            if(!cat[u][v] || k - g[i].tl < 0)   continue;
    
            cat[u][v] --; 
            dfs(v, l + g[i].ln, k - g[i].tl);
            cat[u][v] ++; 
        }
    }

    记忆化搜索

    彻底败给3373了,本菜估计要错出3373应该要两天时间。。。T_T

    POJ 1691 (状压dp)

    题意:有一个棋盘,划分成n个方格,每个方格涂相应的颜色,图色方案如下:

    1、方格i能够被涂色当且仅当i正上方相邻的方格都被涂色;

    2、比如现在要涂col1色,则所有要涂col1色且满足条件以的方格可以同时涂色;

    求喷头至少要换几次能把方格涂完。

    思路:表示真心没相当状态压缩可以这样写,我一直在纠结要怎么预处理棋盘。。。T_T!

    共n个方格,每方格i一给它一个编号 1<<i。所有的方格都被涂色后的状态是 (1<<n) - 1(等比数列求和公式,可以自己算一下,其实从状态累加上就可以看出来。)

    dp[x][i]表示当前状态为x,最后一次涂色的方格是i时的最优值。

    dp[ns][i]转移时可以枚举上一次最后涂色的方格是j的值dp[s][i],然后转移,ns = s|(1<<i),表示i从状态j转移后被染色得到的新状态。详见代码:

    int solve() {
        int s, i, j;
        int m = E(n), tmp, ns;
        REP(i, m)   REP(j, n)   dp[i][j] = inf;
        REP(i, n)   if(!up[i])  dp[(1<<i)][i] = 1;    //第一行,上边没有方块时的情况。
        REP(s, m) {
            REP(i, n) {    //当前状态为s时选一个没有被染色的方格i进行转移。
                if(s&(1<<i))  continue;    //被染色
                if((s&up[i]) != up[i])    continue;    //方格i整上方的方格没有全被染色
                REP(j, n) {    //枚举上一次最后染色为方格j时的情况,通过这个情况转移到i。
                    if((s&(1<<j)) == 0)   continue;    //j未被染色
                    ns = s|(1<<i);   //转移到新状态
                    tmp = dp[s][j];
                    if(p[j].col != p[i].col)    ++tmp;    //颜色相同不用换喷头,颜色不同则要更换。
                    dp[ns][i] = Min(dp[ns][i], tmp);
                }
            }
        }
        int res = inf;
        REP(i, n) {
            res = Min(res, dp[m- 1][i]);
        }
        return res;
    }
  • 相关阅读:
    分析Android中View的工作流程
    什么是分布式锁及正确使用redis实现分布式锁
    机器学习
    吴裕雄--天生自然诗经学习笔记 :醉蓬莱·渐亭皋叶下
    吴裕雄--天生自然诗经学习笔记 :节节高·题洞庭鹿角庙壁
    吴裕雄--天生自然诗经学习笔记 :浪淘沙
    吴裕雄--天生自然诗经学习笔记 :陇头歌辞三首
    吴裕雄--天生自然诗经学习笔记 :贾人食言
    吴裕雄--天生自然诗经学习笔记 :早秋三首
    吴裕雄--天生自然诗经学习笔记 :长相思·惜梅
  • 原文地址:https://www.cnblogs.com/vongang/p/2503415.html
Copyright © 2011-2022 走看看