Timus 1005 & 1009

Problem 1005

问题:一堆石头划分问题,将一堆石头划分成两堆,使这两堆石头之间的重量差最小。

输入:第一行---石头的总数量(1~20)

           第二行---各石头的重量,之间用空格间隔(每个石头重量在1~100000)

输出:两堆石头最小的重量差。

实现代码:

using System;

namespace Q1005
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = Int16.Parse(Console.ReadLine());
            int[] array = new int[num];
            string[] str = Console.ReadLine().Split();
            for (int i = 0; i < num; i++)
                array[i] = Int32.Parse(str[i]);
            int min = MinDifferent(array);
            Console.WriteLine("{0}", min);
        }
        //0-1背包方法
        static int MinDifferent(int[] array)
        {
            int sum=0;
            for (int i = 0; i < array.Length; i++)
                sum += array[i];
            int[] dp = new int[sum+1];
            //背包问题,此背包能够容纳全部的值,且物品的价值等于物品的大小
            //且dp[k]记录的是背包容量为k时的最大值
            for (int i = 0; i < array.Length; i++)
                for (int k = sum; k >= array[i]; k--)
                    dp[k] = Math.Max(dp[k], dp[k - array[i]] + array[i]);
            int min = Int32.MaxValue;
            //找出其中容量为k时的最大值使之与sum/2最接近
            for (int i = 0; i <= sum; i++)
                if (Math.Abs(sum/2 - dp[i]) < min)
                    min = Math.Abs(sum / 2 - dp[i]);
            return (min*2+sum%2);
        }
    }
}

主要知识点:

  1. 0-1背包 :参见http://www.cnblogs.com/fly1988happy/archive/2011/12/13/2285377.html

此问题的暴力解法,参见:比较灵活的暴力法,利用移位http://www.cnblogs.com/skyivben/archive/2008/07/26/1251907.html

或利用每个石头之间总共有的+,-情况:

http://blog.163.com/yinson_lin/blog/static/22120172008112552832626/

Problem 1009

问题:N位的K进制数个数,其中此K进制数个数有一定的限制条件:

1. 两个位之间包含两个0及以上0的不属于,如 10010不属于5进制数。

2. 最高位不允许为0,如011不属于3进制数。

输入:第一行---N(位数---取N>=2)

           第二行---K(进制---取2<=K<=10)

且要求N+K<=18

输出:符合要求的K进制数总个数

实现代码:

using System;

namespace Q1009
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Int16.Parse(Console.ReadLine());
            int k = Int16.Parse(Console.ReadLine());

            Console.WriteLine(DPTotal(k, n));
            Console.WriteLine(TotalNum(k, n));
            Console.ReadKey();
        }

        static int TotalNum(int k, int n)
        {
            int[] store = new int[n + 1];
            //1位数和2位数的情况
            store[1] = k - 1;
            store[2] = (k - 1) * k;
            //采用归纳法得出的结论
            for (int i = 3; i <=n; i++)
                store[i] = (k - 1) * (store[i - 1] + store[i - 2]);
            return store[n];
        }
   }
}

主要知识点:

  1. 在于获取表达式 store[i] = (k - 1) * (store[i - 1] + store[i - 2]);

进一步归纳便可得出上式。

更详细的见:http://www.cnblogs.com/skyivben/archive/2008/07/04/1235062.html

方法二:暴力求解

static int DPTotal(int k,int n)
{
    //dp[i,j]用于记录第i位第j个值得个数
    int[,] dp = new int[n+1, k];
    for (int i = 1; i < k; i++)
        dp[1, i] = 1;
    for(int i=2;i<n+1;i++)
        for(int j=0;j<k;j++)
        {
            if (j == 0)
                for(int m=1;m<k;m++)
                    dp[i, j] += dp[i - 1, m];
            if(j!=0)
                for (int m = 0; m < k; m++)
                    dp[i, j] += dp[i - 1, m];
        }
    int sum=0;
    for (int i = 0; i < k; i++)
        sum += dp[n, i];
    return sum;
}

主要知识点:用数组记录每个结果。

但比较奇怪的发现:方法2既然比方法1用时更短(感觉明显不正常吧!!!)

上面是方法2的结果=。=

时间: 2024-10-15 16:44:01

Timus 1005 & 1009的相关文章

python字符串(大小写、判断、查找、分割、拼接、裁剪、替换、格式化)

一.通用操作 1.Python len() 方法返回对象(字符.列表.元组等)长度或项目个数. 语法 len()方法语法: len( q ) 参数 q -- 对象. 返回值 返回对象长度. 实例 以下实例展示了 len() 的使用方法: >>>str = "runoob" >>> len(str) # 字符串长度 6 >>> l = [1,2,3,4,5] >>> len(l) # 列表元素个数 5 2.pytho

【贪心专题】HDU 1009 FatMouse&#39; Trade (贪心选取)

链接:click here~~ 题意:老鼠准备了M磅猫食,准备拿这些猫食跟猫交换自己喜欢的食物.有N个房间,每个房间里面都有食物.你可以得到J[i]单位的食物,但你需要付出F[i]单位的的猫食. 计算M磅猫食可以获得最多食物的重量. [解题思路]贪心算法,求最优解.将J[i]/F[i]的值从大到小排列,每次取最大的,局部最优,达到全局最优,从而获得最大值. 代码: // 贪心策略,优先选择投资最大的房间,每选择一次,交换次数依次减少,最后的次数用于价值最小的 //注意精度转化:1.0*(int

【HDU 1009】FatMouse&#39; Trade

题 Description FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean. The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of c

timus 1242. Werewolf【队列+结构体】

题目链接http://acm.timus.ru/problem.aspx?space=1&num=1242 大致题意:村庄里有几个人不幸被害,是狼人干的!(插一句,这里可以想到一部电影<狼人>,很惊悚),现在就是需要找出可能是狼人的村民! 已知狼人不会去杀自己的祖宗,也不会杀自己的后代.狼人的父母不超过2个人!(儿女?这个不清楚). 这里给出村里人数n(编号1~n), 给出关系a b 其中a是b的子(女),b是a的父(母) 也给出被害村民的编号. 递增输出可能是狼人的村民的编号,如果没

HDU 1009 FatMouse&#39; Trade (贪心算法)

题意:就是老鼠要用猫粮换粮食,第i个房间一些东西,要用东西去换,可以不全换.问给定的猫粮最多能换多少粮食. 析:贪心算法.我们先算出来每个房间物品的平均价格是多少,肯定越低越好,并且如果能全换就全换,如果不能, 肯定是最后一次了,就把剩下全部换了,看看能换多少.求和. 代码如下: #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <v

HDU ACM 1009 FatMouse&#39; Trade

分析:贪心,每次优先取需要食物的重量和猫食的重量相比最大的,所以先要按比值进行排序,注意J[i]和B[i]要声明为实型,声明为整形就挂了. #include<iostream> #include<algorithm> using namespace std; struct FAT { double f,j; double avg; } fat[1005]; bool cmp(FAT a,FAT b) { if(a.avg<b.avg) return true; else re

csu 1009 抛硬币

C - 抛硬币 CSU - 1009 James得到了一堆有趣的硬币,于是决定用这些硬币跟朋友们玩个小游戏.在一个N行M列的表格上,每一个第i行第j列的格子上都放有一枚James的硬币,抛该硬币正面朝上的概率为Pij,所有抛硬币事件两两之间是相互独立的. 现在,玩家在M列硬币中,从每一列里各选择1枚,共M枚,构成一组.如此重复选择N组出来,且保证被选择过的硬币不能再选.选好组之后,每组的M枚硬币各抛一次,如果都是正面朝上,则该组胜利,总分赢得1分:否则该组失败,总分不加也不减.请问,如果让你自行

HDU 1009:FatMouse&amp;#39; Trade(简单贪心)

FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 41982    Accepted Submission(s): 13962 Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats g

HDU 1009:FatMouse&#39; Trade(简单贪心)

FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 41982    Accepted Submission(s): 13962 Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats g