PTA 7-4 Hand-made Cream c语言版

题目

Suppose you are a baker planning to bake some hand-made cream breads.

To bake a cream bread, we need to use one slice of bread and one kind of cream. Each hand-made cream bread has a taste score to describe how delicious it is, which is obtained by multiplying the taste score for bread and the taste score for cream. (The taste scores could be negative, howerver, two negative tast scores can still produce delicious cream bread.)

The bread and cream are stored separately.

The constraint is that you need to examine the breads in a given order, and for each piece of bread, you have to decide immediately (without looking at the remaining breads) whether you would like to take it.

After you are finished with breads, you will take the same amount of cream in the same manner. The breads and creams you take will be paired in the same order as you take them.

Given N taste scores for bread and M taste scores for cream, you are supposed to calculate the maximum total taste scores for all hand-made cream bread.

输入

Each input file contains one test case. For each case, the first line contains two integers N and M (1≤N,M≤103), which are the numbers of bread and cream, respectively.

The second line gives N taste scores for bread.

The third line gives M taste scores for cream.

The taste scores are integers in [−103,103].

All the numbers in a line are separated by a space.

输出

Print in a line the maximum total taste score.

输入样例:

3 4

-1 10 8

10 8 11 9

输出样例:

188

本题的大意是输入一个有N个数据的面包美味指数数组和有M个数据的奶油美味指数数组,限制为必须按照给定的顺序检查面包,并立刻决定是否选择此面包(不可以遍历后面的面包),吃完面包后会以相同的方式吃下奶油,二者美味指数相乘为总美味指数,要求求出能到手的最大总美味指数。

这道题是一个典型需要动态规划来实现的题目,动态规划在我个人的理解就是构造一个数组,这个数组可以通过你自己的推导式来从某一个固定值的点来推导出整个数组,从而实现题目的要求。本题给了一个面包数组和奶油数组,所以我想可以构造一个N*M的一个二维数组来存储每个位置在当前的最大总美味指数。这样推导到(N,M)点的时候数组中最大值就是我要获取的最大总美味指数了。

代码如下
#include <stdio.h>
#include <stdlib.h>

int max(int a,int b)//比较最大值
{
    return a>b?a:b;
}

int max_4(int a,int b,int c,int d){//选出四个数之间最大值
    return max(max(a,b),max(c,d));
}

int main()
{
    //输入面包数组和奶油数组
    int N,M;
    scanf("%d %d",&N,&M);
    int A[N];
    int B[M];
    for(int i=0;i<N;i++){
        scanf("%d",&A[i]);
    }
    for(int i=0;i<M;i++){
        scanf("%d",&B[i]);
    }
    int result=0;//结果保存在这里
    int dp[N][M];//推导数组
    dp[0][0]=A[0]*B[0];
    //主体部分
    for(int i=0;i<N;i++){//遍历数组
        for(int j=0;j<M;j++){
            if(i==0&&j!=0){//在第一行的时候只用比较是自己和左侧大小
                dp[i][j]=max(A[i]*B[j],dp[i][j-1]);
            }
            if(j==0&&i!=0){//在第一列的时候只用比较自己和上侧大小
                dp[i][j]=max(A[i]*B[j],dp[i-1][j]);
            }
            if(j!=0&&i!=0){
                //在中间的时候就比较复杂,需要比较自己当前,上侧和左侧,以及左上侧的最大值加上当前之间大小
                dp[i][j]=max_4(A[i]*B[j],dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+A[i]*B[j]);
            }
            if(dp[i][j]>result){//不断更新最大值
                result=dp[i][j];
            }
        }
    }
    printf("%d\n",result);//输出
}

为什么会想出这个推导式呢?因为题目规定了面包和奶油只能选当前,因此比较最大值的时候对于普适情况(i和j都不等于0)就有四种情况:从当前点重新开始、保留之前值(左侧或上侧)、继续计算最大值,只需要计算四个最大值即为当前点的最大总美味指数。

运行情况

感悟

这是我的第一篇博客,尝试写了一下PTA的算法题目,如果有错误请随时指正,在这篇博客中我将自己学习动态规划的一些心得体会也加入进去,尽量让大家能看懂我的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值