zoukankan      html  css  js  c++  java
  • 算法小玩意

    N皇后问题

    N*N的棋盘上摆上N个皇后,使皇后不会相互攻击。

    public class NQueenPuzzle
    {
        private readonly int queenAmount;
        private readonly int[] xLocations;

        private int solutionCount = 0;

        public NQueenPuzzle(int n)
        {
            queenAmount = n;
            xLocations = new int[queenAmount];
        }

        //使用栈求解
        public void Solve_stack()
        {
            Stack<int> lastPos = new Stack<int>(queenAmount);
            lastPos.Push(-1);
            while (lastPos.Count > 0)
            {
                var s = lastPos.Pop();
                for (int i = s + 1; i < queenAmount; i++)
                {
                    var k = lastPos.Count;
                    xLocations[k] = i;
                    if (this.Validate(k))
                    {
                        if (k == queenAmount - 1)
                        {
                            this.PrintResult();
                            return;
                        }

                        lastPos.Push(i);
                        lastPos.Push(-1);
                        break;
                    }
                }
            }
        }

        //使用递归求解
        public void Solve()
        {
            Stopwatch sw = Stopwatch.StartNew();
            this.Locate(0);
            Console.WriteLine("time cost to solve puzzle: {0:g}", sw.Elapsed);

            if (solutionCount == 0)
            {
                Console.WriteLine("No result for puzzle with {0} queen", queenAmount);
            }
            else
            {
                Console.WriteLine("total {0} result for puzzle with {0} queen", solutionCount, queenAmount);
            }
        }

        private void Locate(int k)
        {
            if (k == queenAmount)
            {
                solutionCount++;
                Console.WriteLine("*** result {0} *****", this.solutionCount);
                this.PrintResult();
                return;
            }


            for (int i = 0; i < queenAmount; i++)
            {
                xLocations[k] = i;

                if (this.Validate(k))
                {
                    Locate(k + 1);
                }
            }
        }

        private void PrintResult()
        {
            for (int i = 0; i < this.queenAmount; i++)
            {
                for (int j = 0; j < this.queenAmount; j++)
                {
                    Console.Write(j == this.xLocations[i] ? "x " : "- ");
                }

                Console.WriteLine();
            }

            Console.WriteLine();
        }

        private bool Validate(int k)
        {
            bool valid = true;
            for (int j = 0; j < k; j++)
            {
                if (this.xLocations[j] == this.xLocations[k] || Math.Abs(this.xLocations[j] - this.xLocations[k]) == Math.Abs(j - k))
                {
                    valid = false;
                    break;
                }
            }
            return valid;
        }
    }

    使用下面的方法输出8皇后解决方案。

    NQueenPuzzle puzzle = new NQueenPuzzle(8);
    puzzle.Solve();

    0-1背包问题

    一组宝石,价值对应values,重量对应weight,一个背包最大承重capcity,求怎样选择宝石,可使背包装下价值最多?

    public class BagPack0_1
    {
        private int[] values;

        private int[] weight;

        private int capcity;

        private int n;

        public BagPack0_1(int[] v, int[] w, int c)
        {
            values = v;
            weight = w;
            capcity = c;
            n = values.Length;
        }

        public void Solve()
        {
            int[,] M = new int[n + 1, capcity + 1];

            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= capcity; j++)
                {
                    if (j < weight[i - 1])
                    {
                        M[i, j] = M[i - 1, j];
                    }
                    else
                    {
                        M[i, j] = Math.Max(M[i - 1, j], M[i - 1, j - weight[i - 1]] + values[i - 1]);
                    }
                }
            }


            Console.WriteLine("max values:{0}", M[n, capcity]);

            this.ShowResult(M, n, capcity);
        }

        private void ShowResult(int[,] M, int i, int j)
        {
            if (i == 0 || j == 0)
            {
                return;
            }
            if (j >= weight[i - 1] && M[i, j] == M[i - 1, j - weight[i - 1]] + values[i - 1])
            {
                this.ShowResult(M, i - 1, j - weight[i - 1]);
                Console.WriteLine("index:{0}, weight:{1}, value:{2} selected ", i, weight[i - 1], values[i - 1]);
            }
            else
            {
                this.ShowResult(M, i - 1, j);
            }
        }

    }

    测试用例:

    int[] w = { 1, 3, 4, 5, 6, 2, 4, 8, 10 };
    int[] v = { 4, 2, 1, 10, 12, 2, 30, 40, 10 };
    int capacity = 36;
    BagPack0_1 bp = new BagPack0_1(v, w, capacity);

    bp.Solve();

    最大子串问题

    两个数组A、B,求最大子串。
    public class MaxSubString<T>
    {
        private T[] A;

        private T[] B;

        private int m;

        private int n;

        public MaxSubString(T[] A, T[] B)
        {
            this.A = A;
            this.B = B;
            m = A.Length + 1;
            n = B.Length + 1;
        }

        //最大子串引申问题。两个字符串最长相同子串。
        public void Solve_continuous()
        {
            var M = new int[m, n];
            int maxLen = 0;
            int pos = 0;

            for (int i = 1; i < m; i++)
            {
                for (int j = 1; j < n; j++)
                {
                    M[i, j] = object.Equals(A[i - 1], B[j - 1]) ? M[i - 1, j - 1] + 1 : 0;
                    if (M[i, j] > maxLen)
                    {
                        maxLen = M[i, j];
                        pos = i;
                    }
                }
            }

            Console.WriteLine("maxLen is:{0}", maxLen);

            for (int i = maxLen; i > 0; i--)
            {
                Console.Write(A[pos - i].ToString() + ",");
            }
        }

        //数组M记录最大子串长度
        public void Solve2()
        {
            var M = new int[m, n];

            for (int i = 1; i < m; i++)
            {
                for (int j = 1; j < n; j++)
                {
                    if (object.Equals(A[i - 1], B[j - 1]))
                    {
                        M[i, j] = M[i - 1, j - 1] + 1;
                    }
                    else
                    {
                        if (M[i - 1, j] > M[i, j - 1])
                        {
                            M[i, j] = M[i - 1, j];
                        }
                        else
                        {
                            M[i, j] = M[i, j - 1];
                        }
                    }
                }
            }

            this.ShowResult2(M, m - 1, n - 1);
            Console.WriteLine();
        }

        private void ShowResult2(int[,] M, int i, int j)
        {
            if (i == 0 || j == 0)
            {
                return;
            }

            if (M[i, j] == M[i - 1, j])
            {
                this.ShowResult2(M, i - 1, j);
            }
            else if (M[i, j] == M[i, j - 1])
            {
                this.ShowResult2(M, i, j - 1);
            }
            else
            {
                this.ShowResult2(M, i - 1, j - 1);
                Console.Write("," + A[i - 1]);
            }
        }

        //使用辅助数组S,记录数组元素是否是最大子串成员
        public void Solve1()
        {
            int[,] M = new int[m, n];
            int[,] S = new int[m, n];//1left,2up,3select

            for (int i = 0; i < m; i++)
            {
                M[i, 0] = 0;
            }
            for (int i = 0; i < n; i++)
            {
                M[0, i] = 0;
            }

            for (int i = 1; i < m; i++)
            {
                for (int j = 1; j < n; j++)
                {
                    if (object.Equals(A[i - 1], B[j - 1]))
                    {
                        M[i, j] = M[i - 1, j - 1] + 1;
                        S[i, j] = 3;
                    }
                    else
                    {
                        if (M[i - 1, j] > M[i, j - 1])
                        {
                            M[i, j] = M[i - 1, j];
                            S[i, j] = 1;
                        }
                        else
                        {
                            M[i, j] = M[i, j - 1];
                            S[i, j] = 2;
                        }
                    }
                }
            }

            Console.WriteLine("Max sub list count:{0}", M[m - 1, n - 1]);

            ShowResult(S, m - 1, n - 1);
            Console.WriteLine();
        }

        private void ShowResult(int[,] S, int i, int j)
        {
            if (i == 0 || j == 0)
            {
                return;
            }

            if (S[i, j] == 3)
            {
                ShowResult(S, i - 1, j - 1);
                Console.Write("," + A[i - 1]);
            }
            else if (S[i, j] == 1)
            {
                ShowResult(S, i - 1, j);
            }
            else if (S[i, j] == 2)
            {
                ShowResult(S, i, j - 1);
            }
        }

    }

    测试:

    int[] A = new[] { 1, 2, 3, 4 };
    int[] B = { 1, 2, 1, 2, 3, 4 };

    MaxSubString<int> mss = new MaxSubString<int>(A, B);
    mss.Solve1();

  • 相关阅读:
    LNMP源码安装配置
    CentOS6 Apache配置详解(上)
    CentOS6 Apache配置详解(中)
    BZOJ4152 AMPPZ2014 The Captain(最短路)
    BZOJ4028 HEOI2015公约数数列(分块)
    Codeforces Round #517 Div. 1翻车记
    BZOJ4027 HEOI2015兔子与樱花(贪心)
    BZOJ4000 TJOI2015棋盘(状压dp+矩阵快速幂)
    Codeforces Round #510 Div. 2 Virtual Participate记
    BZOJ5190 Usaco2018 Jan Stamp Painting(动态规划)
  • 原文地址:https://www.cnblogs.com/lingshf/p/5438731.html
Copyright © 2011-2022 走看看