2016-6-19 动态规划,贪心算法练习

Posted tech-chen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016-6-19 动态规划,贪心算法练习相关的知识,希望对你有一定的参考价值。

DP:1.codevs 1493 糖果

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
 
题目描述 Description

最近小修很高兴,因为她的k个外甥就要来她家里玩了。她上超市买了一大堆糖果,总共有n颗。

小修准备把所有的糖果分成k堆(当然每一堆至少要有一颗糖果)。可是到底有多少种分法呢?

她冥思苦想不得其解,你能帮助她吗?

输入描述 Input Description

两个用空格分开的整数n, k(n<=60000, k<=100)。

输出描述 Output Description

仅一个数:方案总数。

注意:因为方案数可能很多,你仅需要输出结果mod 10000的值。

样例输入 Sample Input

4 2

样例输出 Sample Output

2

 1 #define N 60005
 2 #define K 105
 3 #include<iostream>
 4 using namespace std;
 5 #include<cstdio>
 6 #define mod 10000
 7 int n,k;
 8 int f[N][K];
 9 int main()
10 {
11     scanf("%d%d",&n,&k);
12     for(int i=1;i<=n;++i)
13       for(int j=1;j<=i&&j<=k;++j)
14       {
15           if(j==1)
16            f[i][j]=1;
17           else f[i][j]=(f[i-1][j-1]+f[i-j][j])%mod;
18       }
19     printf("%d\n",f[n][k]);
20     return 0;
21 }

 

贪心:2.1052 地鼠游戏

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
题目描述 Description

    王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于经常总结、完善自己的学习方法,所以他总能在每次考试中得到优异的分数,这一切很大程度上是由于他是一个追求效率的人。

    但王钢也是一个喜欢玩的人,平时在学校学习他努力克制自己玩,可在星期天他却会抽一定的时间让自己玩一下,他的爸爸妈妈也比较信任他的学习能力和学习习惯,所以在星期天也不会象其他家长一样对他抓紧,而是允许他在星期天上午可以自由支配时间。

    地鼠游戏是一项需要反应速度和敏捷判断力的游戏。游戏开始时,会在地板上一下子冒出很多地鼠来,然后等你用榔头去敲击这些地鼠,每个地鼠被敲击后,将会增加相应的游戏分值。问题是这些地鼠不会傻傻地等你去敲击,它总会在冒出一会时间后又钻到地板下面去(而且再也不上来),每个地鼠冒出后停留的时间可能是不同的,而且每个地鼠被敲击后增加的游戏分值也可能是不同,为了胜出,游戏参与者就必须根据每个地鼠的特性,有选择地尽快敲击一些地鼠,使得总的得分最大。

这个极具挑战性的游戏王钢特别喜欢,最近他经常在星期天上午玩这个游戏,慢慢地他不但敲击速度越来越快(敲击每个地鼠所需要的耗时是1秒),而且他还发现了游戏的一些特征,那就是每次游戏重新开始后,某个地鼠冒出来后停留的时间都是固定的,而且他记录了每个地鼠被敲击后将会增加的分值。于是,他在每次游戏开始后总能有次序地选择敲击不同的地鼠,保证每次得到最大的总分值。

输入描述 Input Description

    输入包含3行,第一行包含一个整数n(1<=n<=100)表示有n个地鼠从地上冒出来,第二行n个用空格分隔的整数表示每个地鼠冒出后停留的时间,第三行n个用空格分隔的整数表示每个地鼠被敲击后会增加的分值(<=100)。每行中第i个数都表示第i个地鼠的信息。

输出描述 Output Description

    输出只有一行一个整数,表示王钢所能获得的最大游戏总分值。

样例输入 Sample Input

5

5  3  6  1  4

7  9  2  1  5

样例输出 Sample Output

24

/*一开始理解错了,以为是个线段覆盖,后来发现线段只有上下界,具体的端点是没有的。
贪心法:处理出每个点在最大停留时间的剩余时间,先处理剩余时间少的,也就是在一个地鼠即将下地的前一秒敲它。如果有同样好几个时间少,就取分数最大的。
*/
#include<iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#define N 132
struct Ds{
    int tim,fs;
    bool operator<(Ds p)
    const{return tim<p.tim;}
}ds[120];
int n,maxsytim=0,ans=0,sum;
bool visit[N];
void input()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&ds[i].tim);
        sum=max(sum,ds[i].tim);
    }
    for(int i=1;i<=n;++i)
    {
        ds[i].tim=sum-ds[i].tim;
        maxsytim=max(maxsytim,ds[i].tim);
    }
    for(int i=1;i<=n;++i)
    scanf("%d",&ds[i].fs);
      
}
int main()
{
    input();
    sort(ds+1,ds+n+1);
    for(int j=0;j<sum;++j)/*注意sum这里不是maxsysum,因为这个不是敲地鼠的总时间,而且要小于sum,因为敲一个地鼠需要一秒钟*/
    {
        int temp,kkk=0;
        for(int i=1;i<=n;++i)
        {
            if(ds[i].tim<=j&&!visit[i]&&ds[i].fs>kkk)
            {
                kkk=ds[i].fs;
                temp=i;
            }

        }
        visit[temp]=true;
        ans+=kkk;
    }
    printf("%d",ans);
    return 0;
}

 

3.NOI 1757:神奇的口袋

总时间限制: 
10000ms
 
内存限制: 
65536kB
描述
有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式。
输入
输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目。接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2……an的值。
输出
输出不同的选择物品的方式的数目。
样例输入
3
20
20
20
样例输出
3
#include<iostream>
using namespace std;
#include<cstdio>
int n;
int a[25];
int f[45]={0};
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
      scanf("%d",&a[i]);
    f[0]=1;
    for(int i=1;i<=n;++i)
      for(int j=40;j>=a[i];--j)
      f[j]+=f[j-a[i]];
    printf("%d\n",f[40]);
    return 0;
}

 

4.NOI 2393:Going to the Movies

总时间限制: 
10000ms
 
单个测试点时间限制: 
1000ms
 
内存限制: 
65536kB
描述
Farmer John is taking some of his cows to the movies! While his truck has a limited capacity of C (100 <= C <= 5000) kilograms, he wants to take the cows that, in aggregate, weigh as much as possible without exceeding the limit C.

Given N (1 <= N <= 16) cows and their respective weights W_i, determine the weight of the heaviest group of cows that FJ can take to the movies.
输入
* Line 1: Two space-separated integers: C and N

* Lines 2..N+1: Line i+1 contains a single integer: W_i
输出
* Line 1: A single integer that is the weight of the heaviest group of cows that can go to the movies
样例输入
259 5
81
58
42
33
61
样例输出
242
提示
81+58+42+61 = 242;
this is the best possible sum
#include<iostream>
using namespace std;
#include<cstdio>
#define C 5101
bool f[C]={0};
int n,c;
int w[20];
int main()
{
    scanf("%d%d",&c,&n);
    for(int i=1;i<=n;++i)
      scanf("%d",&w[i]);
    f[0]=true;
    for(int i=1;i<=n;++i) 
      for(int j=c;j>=w[i];--j)
      f[j]=f[j]||f[j-w[i]];
    for(int j=c;j>=0;--j)
    {
        if(f[j])
        {
            printf("%d\n",j);
            break;
        }
    }
    return 0;
}

5

以上是关于2016-6-19 动态规划,贪心算法练习的主要内容,如果未能解决你的问题,请参考以下文章

动态规划算法介绍,以及和贪心算法的比较

openjudge-NOI 2.6基本算法之动态规划 专题题解目录

python_分治算法贪心算法动态规划算法

安琪拉教鲁班学算法之动态规划

算法进阶——贪心与动态规划

算法基础--贪心算法