Code quay lui bằng C# tìm tổ hợp, chỉnh hợp chập k của n

Đăng bởi : 4/13/2014

thuvienwinform - Thuật toán trâu bò quen thuộc và khá hữu ích trong việc code. Để tìm tổ hợp đơn giản là tìm một dãy số thỏa mãn điều kiện sau:
- Các số đều khác nhau
- Số sau lớn hơn số trước
- Các bộ số không trùng lặp nhau
-...

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace QuayLuiTimToHop
{
    class Program
    {
        #region Khai báo
        static int n, k;
        static int[] a, dau;
        #endregion

        #region THủ tục
        private static void Xuat(int i)
        {
            for (int j = 1; j <= k; j++)
                Console.Write(a[j] + " ");
            Console.WriteLine();
        }

        private static void Duyet(int i)
        {
            if (i > k) Xuat(i);
            else
            {
                int j;
                for (j = a[i - 1]; j <= n; j++)
                {
                    if (dau[j] == 0)
                    {
                        a[i] = j;
                        dau[j] = 1;
                        Duyet(i+1);
                        dau[j] = 0;
                    }
                }
            }
        }
        #endregion

        static void Main(string[] args)
        {
            #region Đầu vào
            Console.Write("Nhap va n: ");
            n = Convert.ToInt32(Console.ReadLine());
            Console.Write("Nhap va k: ");
            k = Convert.ToInt32(Console.ReadLine());
            a = new int[n+1];
            dau = new int[n+1];
            for (int i = 0; i < n + 1; i++)
                dau[i] = 0;
            #endregion

            #region Xử lí
            Console.WriteLine("To hop chap " + k + " cua " + n + ": ");
            a[0] = 1;
            Duyet(1);
            #endregion

            Console.ReadKey();
        }
    }
}
Dãy cần tìm là a
Thuật toán quay lui với vòng lặp sẽ bắt đầu từ a[i-1] đề thỏa mãn điều kiện các số khác nhau và số sau lớn hơn số trước. Trong quá trình duyệt kết hợp đánh dấu phần tử đã sử dụng để không bị trùng (ở trong này mình dùng mảng dau)
Khi tìm đủ k phần tử cho mảng a thì xuất ra.

Về lí thuyết quay lui có thể tham khảo trong sách giải thuật và lập trình của Lê Minh Hoàng

Với code này chuyển thành tính chỉnh hợp cũng không có gỉ cả, chỉ cẩn thay vòng lặp thành thế này là OK
Các số trong bộ số sẽ không phải là từ a[i-1] nữa mà là từ 1

for (j = 1; j <= n; j++)
{
    if (dau[j] == 0)
    {
        a[i] = j;
        dau[j] = 1;
        Duyet(i+1);
        dau[j] = 0;
    }
}


{ 1 comments }

  1. Hình như bài này trên spoj là COMBIN phải không

    ReplyDelete

Nhận ngay 100$ cho VPS

Mua hàng ủng hộ page

Ủng hộ page

Nhãn

Code (45) Team Foundation Server (17) Database (14) News (14) product (13) toolbox (10) Linq (9) SoftDesign (8) XNA (6) API (5) Project (5) item (4)

- Bản quyền thuộc về Thư Viện WinForm - Giao diện: Metrominimalist - Thiết kế: Johanes Djogan -