upc聪明人的游戏--动态规划

人群淹没,你我不及诉说。一声雁过,往事如昨。只望离别不多,再赏盛世烟火。

                                                 问题 B: 【动态规划】圣诞树

题目描述

圣诞特别礼物挂在一棵圣诞树上,这棵树有n层,每层有一件礼物,每件礼物都有一个价值,有的礼物还有一些连接线,与下层的礼物相连。领取礼物的规则如下:任选一件礼物,它的下面如果有连接线,则可以继续取它连接的礼物,依此类推直至取到没有连接线的礼物才结束。你如果是第一个去取,怎样取才能获得最大的价值呢?请你编一程序解决这一问题。

 

输入

第1行只有一个数据n(n≤100),表示有n层礼物,以下有n行数据,分别表示第1~n层礼物的状态,每行至少由一个数据构成,且第一个数据表示该礼物的价值,后面的数据表示它与哪些层的礼物相连,如果每行只有一个数据则说明这层礼物没有与下层礼物相连,每个数据大小均不超过10000。

 

输出

只有一个数,表示获得的最大价值。

 

样例输入

复制样例数据

3
12 2 3
20
30

样例输出

42
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,b[1010],a[1010][1010],dp[1010],jg;
char c;
int dfs(int x)
{
    if (dp[x]>-1)
        return dp[x];
    dp[x]=b[x];
    for (int i=1; i<=a[x][0]; i++)
            dp[x]=max(dp[x],dfs(a[x][i])+b[x]);
    return dp[x];
}
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; ++i)
    {
        scanf("%d",&b[i]);
        scanf("%c",&c);
        while (c!='\n')
        {
            scanf("%d",&a[i][++a[i][0]]);
            scanf("%c",&c);
        }
    }
    memset(dp,-1,sizeof(dp));
    for(int i=1; i<=n; i++)
        jg=max(jg,dfs(i));
    printf("%d\n",jg);
    return 0;
}

                                                        问题 C: 传球游戏

题目描述

上体育课时,墨老师经常带着同学们一起做游戏。这次,墨老师带着同学们一起做传球游戏,游戏规则是这样的:N个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时拿着球没传出去的那个同学就是败者,要给大家表演一个节目。

聪明的张琪曼提出一个有趣的问题:有多少种不同的传球方法可以使得从张琪曼手里开始传的球,传了M次以后,又回到张琪曼手里。两种传球的方法被称作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有3个同学1号、2号、3号,并假设张琪曼为1号,球传了3次回到张琪曼手里的方式有1à2à3à1和1à3à2à1,共两种。

 

输入

有两个用空格隔开的整数N,M(3≤N≤30,1≤M≤30)。

 

输出

有一个整数,表示符合题目的方法数。

 

样例输入

复制样例数据

3 3

样例输出

2
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
int N,M;
int dp[50][50];//dp表示传球i次到j号球的方法数
int main(){
    scanf("%d%d",&N,&M);
    dp[0][1]=1;
    for(int i=1;i<=M;i++){
        for(int j=1;j<=N;j++){
            if(j==1)
                dp[i][j]+=dp[i-1][N]+dp[i-1][j+1];
            else if(j==N)
                dp[i][j]+=dp[i-1][1]+dp[i-1][j-1];
            else
                dp[i][j]+=dp[i-1][j-1]+dp[i-1][j+1];
        }
    }
    printf("%d\n",dp[M][1]);
    return 0;
}

                                        问题 D: 【动态规划】黑熊过河

题目描述

晶晶的爸爸给晶晶出了一道难题:有一只黑熊想过河,但河很宽,黑熊不会游泳,只能借助河面上的石墩跳过去,它可以一次跳一墩,也可以一次跳两墩,但是每跳一次都会耗费一定的能量,黑熊最终可能因能量不够而掉入水中。所幸的是,有些石墩上放了一些食物,这些食物可以给黑熊增加一定的能量。问黑熊能否利用这些石墩安全地抵达对岸?请计算出抵达对岸后剩余能量的最大值。

 

输入

第1行包含两个整数P(黑熊的初始能量),Q(黑熊每次起跳时耗费的能量),0≤P,Q≤1000;
第2行只有一个整数n(1≤n≤106),即河中石墩的数目;
第3行有n个整数,即每个石墩上食物的能量值ai(0≤ai≤1000)。

 

输出

仅1行,若黑熊能抵达对岸,输出抵达对岸后剩余能量的最大值;若不能,则输出“NO”。

 

样例输入

复制样例数据

12 5
5
0 5 2 0 7

样例输出

6
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
int P,Q,N,fg;
int s[1000010],dp[1000010];
int main(){
    scanf("%d%d",&P,&Q);
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
        scanf("%d",&s[i]);
        dp[0]=P;
        if(P-Q>=0)
            dp[1]=P-Q+s[1];
        else
            dp[1]=-inf;//初始化dp[0],dp[1]的值
        for(int i=2;i<=N+1;i++){
            fg=0;
            if(dp[i-1]-Q>=0)
                fg=1,dp[i]=max(dp[i],dp[i-1]-Q+s[i]);
            if(dp[i-2]-Q>=0)
                fg=1,dp[i]=max(dp[i],dp[i-2]-Q+s[i]);
            if(fg==0)
                dp[i]=-inf;
        }
        if(dp[N+1]<0)
            printf("NO\n");
        else
            printf("%d\n",dp[N+1]);
    return 0;
}

 

你可能感兴趣的:(石油大学)