日期:2014-05-18  浏览次数:20766 次

算法问题
任给1<=n<=20个不同等非零正整数,每个正整数最多使用一次,请问这n个正整数能够加和的结果共有多少种?
这个是我们学校软件技能大赛的题目,大家讨论下啊
用C#写下啊、。。呵呵


------解决方案--------------------
C# code

    static void Main(string[] args)
    {
        int i = GetCombinationCount(new int[] { 1, 2, 3 });   //i=6
    }

    static int GetCombinationCount(int[] nums)
    {
        Dictionary<int, int> sums = new Dictionary<int, int>();
        int combinations = 1 << nums.Length;

        for (int i = 1; i < combinations; i++)
        {
            string masks = Convert.ToString(i, 2).PadLeft(nums.Length, '0');
            int sum = 0;
            for (int j = 0; j < masks.Length; j++)
            {
                if (masks[j] == '1') sum += nums[j];
            }
            sums[sum] = 1;
        }
        return sums.Count;
    }
}

------解决方案--------------------
这样写可能更能对一些算法派的胃口:
原理简单的说就是n个灯(或n bits),用或者不用,总的组合等于2^n
C# code

static int GetCombinationCount(int[] nums)
{
    Dictionary<int, int> sums = new Dictionary<int, int>();
    int combinations = 1 << nums.Length;

    for (int i = 1; i < combinations; i++)
    {
        int sum = 0, mask = i;
        foreach (int n in nums)
        {
            if (mask == 0) break;
            if (mask % 2 == 1) sum += n;
            mask >>= 1;
        }
        sums[sum] = 1;
    }
    return sums.Count;
}

------解决方案--------------------
应该有2的n次方-1种:
C# code

        static void Main(string[] args)
        {
            int[] a = { 24, 4, 31, 14, 59 };
            GetCombination(a);
        }


        static string GetBinaryString(int n, int length)
        {
            string result = string.Empty;
            int mod = 0;
            while (n != 0)
            {
                mod = n % 2;
                n = n / 2;
                result = mod.ToString() + result;
            }
            if (result.Length < length)
                result = result.PadLeft(length, '0');
            return result;
        }

        static void GetCombination(int[] nums)
        {
            double count = Math.Pow(2, nums.Length);
            for (int i = 1; i <= count - 1; i++)
            {
                Console.Write("可能的组合有:");
                string str = GetBinaryString(i, nums.Length);
                int sum = 0;
                for (int j = 0; j < str.Length; j++)
                {
                    if (str[j] == '1')
                    {
                        Console.Write(nums[j] + " ");
                        sum += nums[j];
                    }
                }
                Console.WriteLine("和为:" + sum);
            }
        }