动态规划——解决背包问题

说实话,今天华为的笔试题把握打击坏了,动态规划这么简单的东西,居然没写出来!,我很伤心,所以赶紧私下把他实现出来,看了网上很多别人写的东西,说实话:内容太辣鸡了。还是建议看《图解算法》,推导过程十分易懂,动态规划就是个找zhua转移方程的东西,说白了,就是找递推公式!

 

 

 

再来看个几乎完全一致的问题:物品个数n=5,物品重量w[5]={2,2,6,5,4},物品价值v[5]={6,3,5,4,6}, 背包的最大容量为10,求价值最大化。 

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

#define N  5//宝贝数目
#define V 10//背包总容量

int main()
{    
    //+1的写法(为的就是对下标进行操作),是为了后面动态规划算法的实现,同时,你也可以这么写
/*
    a[N];
    for(int i=1;i<=N;i++)
            scanf("%d",&a[i]);
*/
    int value[N+1]={0, 6, 3, 5, 4, 6}//钱
    int weight[N + 1] = {0, 2, 2, 6, 5, 4}; // 重量
    //钱作为横坐标,重量作为纵坐标    
    int f[N + 1][V + 1] = {0}; // f[i][j]表示在背包容量为j的情况下, 前i件宝贝的最大价值
    
//动态规划核心
//从1开始是有原因的,你看看数组value的赋值情况,还有递推公式中的f[i-1][j],所以i起码要从1开始
//j的话从0,1开始都可以,看你怎么设置了
    for(int i=1;i<=N;i++)
        for(int j=1;j<=10;j++)
            if(<j<weight(i))//已更正完毕
                f[i][j]=f[i-1][j];
            else
            {
                int x=f[i-1][j];
                int y=value(i)+f[i-1][j-weight[i]]
                f[i][j]=x<y?y:x;
            }

    
    for(int i=1;i<=N;i++)
        for(int j=1;j<=10;j++)
           {
            int max=f[1][1];
            if(max<f[i][j])
                max=f[i][j];
           }   
    printf("%d\n",max);
    return 0;
}

参考:https://blog.csdn.net/stpeace/article/details/46700657(为主)

https://www.cnblogs.com/A-S-KirigiriKyoko/p/6036368.html(方法多的参考,)

 

下面说说华为笔试题目2018-8-8

优招第一批,总共三道编程

(1)输入任意一个字符串,将其中的大写字母小写化,小写字母大写化,其它不变

int main
{
    char a[100];
    int i=0;
   while(getchar(a)!='\0')
{
    if(a[i]>='A'  && a[i]<='Z')
        a[i]=a[i]+32;
    else if(a[i]>='a' && a[i]<='z')
        a[i]=a[i]-32;
    else
        a[i]=a[i];

    printf("%d\n",a);
    return 0;
}



(2)DP去解

小偷来到了一个神秘的王宫,突然眼前一亮,发现5个宝贝,每个宝贝的价值都不一样,且重量也不一样,但是小偷的背包携带重量有限,所以他不得不在宝贝中做出选择,才能使偷到的财富最大,请你帮助小偷计算一下。

输入描述:

宝贝价值:6,3,5,4,6
宝贝重量:2,2,6,5,4
小偷背包容量:10

输出描述:

偷到宝贝的总价值:15

示例1

输入

6,3,5,4,6

2,2,6,5,4

10

输出

15

 

#include<stdlib.h>
#include<stdio.h>
#include<string.h>


#define N 5
#define V 10

int main()
{
    //初始化数组要给的大一点,否则会出现数组越界的情况,里面的值按照下标给就可以了
    int a[N+V],b[N+V];
    int all;

	//int a[N+1]={0,6,3,5,4,6};
	//int b[N+1]={0,2,2,6,5,4};
	//all=10;

	//三个scanf这么写,类似于换行了
	//下面的scanf写法就是符合输入,需要加“,”,如果是scanf写成scanf("%d",&a[i])这样,输入的话,得是2 3 4 5 6这种加空格
    for(int i=1;i<=N;i++)
        scanf("%d,",&a[i]);

	for(int i=1;i<=N;i++)
        scanf("%d,",&b[i]);

	scanf("%d",&all);

    int f[N+1][V+1]={0};
    for(int i=1;i<=N;i++)
        for(int j=1;j<=all;j++)
            if(j<b[i])
               f[i][j]=f[i-1][j];
            else
                {
                    int x=f[i-1][j];
                    int y=a[i]+f[i-1][j-b[i]];
                     f[i][j]=x<y?y:x;
                }
    int final=f[1][1];
    for(int i=1;i<=N;i++)
        for(int j=1;j<=all;j++)
            if(f[i][j]>final)
                final=f[i][j];
    printf("%d",final);
	system("pause");
    return 0;
}

 

    原文作者:动态规划
    原文地址: https://blog.csdn.net/u011436427/article/details/81517136
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞