8月4ACM集训之---------背包问题

好想吐槽一下,每一个专题两天,还要努力数排名,对我这样一个比较笨又不是很勤奋的人来说,真心有点吃力,好多东西都只能做到一知半解————要加油了---不然会被鄙视的的

背包——通俗理解就是将背包装满的问题,其要求一般是使其价值最大

01背包:

有N件物品和一个重量为M的背包。(每种物品均只有一件)第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使价值总和最大。

每个物体都有两个属性,value和weight,而背包则有size,用V[i, j]用来表示从前 i 项{u1......ui}(背包中的物品)中取出来的装入体积为size的背包的最大价值。

V[i, j] = 0       若i = 0 或 j = 0;

V[i, j] = V[i - 1, j]    若j < ui.weight;(当物品的重量大于背包承重时,就不巴物品放在里面)

V[i, j] = max{V[i - 1, j], V[i - 1, j - ui.weight] + ui.value}      若i > 0并且j >= ui.weight

简化后的模板未:f[v]=max{f[v],f[v-c]+w}(前i件武平放入容积为v的背包中可获得的最大价值)

完全背包:

每种物品可以放无限放

多重背包问题:

每种物品有一个固定的次数上限

二维费用的背包问题:

二维费用的背包问题是指对于每件物品,具有两种不同的费用,选择这件物品必须同时付出这两种代价,对于每种代价都有一个可付出的最大值(背包容量),求选择物品可以得到最大的价值。设第i件物品所需的两种代价分别为v[i]和u[i],两种代价可付出的最大值(两种背包容量)分别为V和U,物品的价值为w[i]。

例:杭电acm 2602

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int max(int a,int b)
{
    return a>b?a:b;

}
int main()
{
    int t,n,m,dp[10001],i,j;
    int a[10000],b[10000];
    scanf("%d",&t);
    while(t--)
    {

        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=1;i<=n;i++)
        {
        scanf("%d",&b[i]);
        }

        for(i=1;i<=n;i++)
        {
            for(j=m;j>=b[i];j--)
            {
                dp[j]=max(dp[j],dp[j-b[i]]+a[i]);
                
            }
        }

        cout<<dp[m]<<endl;
        

    }
    return 0;
}

杭电     对布的裁剪问题

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

struct node
{
    int val,wei;
} a[155];

int dp[155][155];

int main()
{
    int n,m,k,s,x,y,z,i;
    while(~scanf("%d%d%d%d",&n,&m,&k,&s))
    {
        for(i = 1; i<=k; i++)
            scanf("%d%d",&a[i].val,&a[i].wei);
        memset(dp,0,sizeof(dp));
        for(x = 1; x<=m; x++)
        {
            for(y = 1; y<=k; y++)
            {
                for(z = 1; z<=s; z++)
                {
                    int cnt = 1;
                    while(cnt*a[y].wei<=x && cnt<=z)
                    {
                        dp[x][z] = max(dp[x][z],dp[x-cnt*a[y].wei][z-cnt]+cnt*a[y].val);
                        cnt++;
                    }
                }
            }
            if(dp[x][s]>=n)
            break;
        }
        if(x>m)
        printf("-1\n");
        else
        printf("%d\n",m-x);
    }
    return 0;
}

  

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

struct node
{
    int x,y,v;
}a[20];

int dp[1005][1005];

int main()
{
    int i,j,k,n,X,Y,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&X,&Y);
        for(i = 0;i<n;i++)
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);
        memset(dp,0,sizeof(dp));
        for(i = 0;i<=X;i++)//二维背包
        {
            for(j = 0;j<=Y;j++)
            {
                for(k = 0;k<n;k++)
                {
                    if(i>=a[k].x && j>=a[k].y)
                    dp[i][j] = max(dp[i][j],max((dp[i-a[k].x][j]+dp[a[k].x][j-a[k].y]),(dp[i][j-a[k].y]+dp[i-a[k].x][a[k].y]))+a[k].v);
                    if(i>=a[k].y && j>=a[k].x)
                    dp[i][j] = max(dp[i][j],max((dp[i-a[k].y][j]+dp[a[k].y][j-a[k].x]),(dp[i][j-a[k].x]+dp[i-a[k].y][a[k].x]))+a[k].v);
                }
            }
        }
        printf("%d\n",dp[X][Y]);
    }

    return 0;
}
//求最小价值#include<stdio.h>
#include<string.h>
#include"cstdio"
#include<iostream>
using namespace std;
#define max 10000000;
struct node
{
    int value;
    int weight;
}a[10005];

int dp[10000];
int main()
{
    int t,n,m,m1,m2,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&m1,&m2);
        scanf("%d",&n);
        m=m2-m1;
       for(i=0;i<=m;i++)
           dp[i]=10000000;
        dp[0]=0;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&a[i].value,&a[i].weight);
        }

        for(i=0;i<n;i++)
        {
            for(j=a[i].weight;j<=m;j++)
            {

                if(dp[j]>dp[j-a[i].weight]+a[i].value)
                    dp[j]=dp[j-a[i].weight]+a[i].value;
                
            }
        }
        if(dp[m]==10000000)
            printf("This is impossible.\n");
        else
        printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);
        

    }
    return 0;
}

8月4ACM集训之---------背包问题,布布扣,bubuko.com

时间: 2024-08-24 07:34:12

8月4ACM集训之---------背包问题的相关文章

2019.01.19-2018年6月NEYC集训sequence

题目描述: 茉优最近研究发现,一个人的想愿能力可以认为是字符串S的一个子串S[l,r],而连接值可以认为是这个子串的本质不同子序列个数.现在她想验证她的结论是否正确,于是她给了你Q个询问,希望你帮她来计算,注意空串也是子序列. 因为茉优已经有一个答案了,所以你只要输出ZQ的值检验即可. 思路: 考虑对于取以字符i为结尾的转移矩阵,是除了单位矩阵外,第一列为都为1,恰好表示除了以i为结尾的情况其他情况都*2. 于是构建出每个字母的转移矩阵,是一个53*53的矩阵,叫它C[i]. 对于每一个询问,答

反思2017CCPC网络赛

很遗憾,经历了一个月的集训(7.20-8.18),我们小队在网络赛收获了0题,这... 此刻,我想到的只有担当.我们小队是一体的,每个人的能力都关乎着小队的成绩,所以我有责任做好我的事,我有责任为这个团队带来荣誉. 所以,我会搞好ACM.时间会证明一切. 担当 担当 担当

转载励志奋斗 博文

弱校ACM奋斗史 题解:还记得2年前的一个晚上,我和一个女孩一起写完了这篇文章.写完后,她哭了,我笑了.然后,她走了,我哭了.2年后,我又找到她,这次,我没有让她走掉,她成了我的新娘. 不知道什么时候,开始知道ACM:也不知道什么时候,开始喜欢上ACM.但是,我知道,我喜欢上了,而且不会后悔.我是大一的时候进的学校ACM队,那个时候,一切都是冰冷的,华东理工大学,在别人的眼里,只是每次给别人垫底的学校,次次如此. 但是,我们不甘心,我们从不甘心,当我们主力队员中的一个,一个月拼命集训,瘦了很多的

弱校ACM奋斗史 (转)

题解:还记得2年前的一个晚上,我和一个女孩一起写完了这篇文章.写完后,她哭了,我笑了.然后,她走了,我哭了.2年后,我又找到她,这次,我没有让她走掉,她成了我的新娘. 不知道什么时候,开始知道ACM:也不知道什么时候,开始喜欢上ACM.但是,我知道,我喜欢上了,而且不会后悔.我是大一的时候进的学校ACM队,那个时候,一切都是冰冷的,华东理工大学,在别人的眼里,只是每次给别人垫底的学校,次次如此.但是,我们不甘心,我们从不甘心,当我们主力队员中的一个,一个月拼命集训,瘦了很多的时候,突然,我有一种

转载了两篇别人写的话语

转载:http://acmicpc.info/archives/369 还记得2年前的一个晚上,我和一个女孩一起写完了这篇文章.写完后,她哭了,我笑了.然后,她走了,我哭了.2年后,我又找到她,这次,我没有让她走掉,她成了我的新娘. 不知道什么时候,开始知道ACM:也不知道什么时候,开始喜欢上ACM.但是,我知道,我喜欢上了,而且不会后悔.我是大一的时候进的学校ACM队,那个时候,一切都是冰冷的,华东理工大学,在别人的眼里,只是每次给别人垫底的学校,次次如此. 但是,我们不甘心,我们从不甘心,当

[个人][AFO] OI回忆录 The End

前言 微微颤抖的双手敲击键盘,身处从长沙飞驰的高铁,返回家乡. 我知道终将离别,但我不知道离别到来的如此之快.内心有些怅惘,微微的失落,却是又无可奈何. 没有后悔,没有怨念,有的只是一丝丝不舍,舍不得的却是太多. 是时候做一个完结了,结束,也就意味着一个新的开始. 初识OI 是的,两年前初识OI,我还是一个不谙世事的少年,带着对未来的憧憬,带着对高中的期待,踏入这所全国著名的中学. 缘起,卓越之旅理科夏令营. 我还记得营服背后那句话 "给理想一点时间" 当时并不知道什么叫做竞赛,以为只

个人一个月集训感想。

奔跑中的少年! 不得不再感叹一下. 时间过的真是太快了. 转眼自己也大二了. 真的是转眼之间. 感觉这一年让自己成长了很多.改变了很多. 好久没写日志了. 暑假期间在学校与各路大神一起奋斗了一个月. 为着同一个目标.同一个方向吧. 感觉还是蛮爽的.每天都在收获的日子总是那么快乐. 今天这篇日志就简单的整理一下自己一个暑假跟随ACM队的收获.感受. 经历吧. 或许现在觉得这些说的很有道理.再过一年再回头看看的话.可能觉得自己很傻呢. 1.一个故事. ACM给予我们山科ACM成员一个比别人低的起点,

[NOIP集训]10月16日

今天的文件夹:10月16日.zip 毕竟是第一天,题目比较简单,简单说下做法. T1:对区间按左端点为第一关键字,右端点为第二关键字进行排序,然后计算可合并的区间,即前面区间的右端点不小于后面区间的左端点,这样合并后,新区间的右端点为二者右端点中的较大值. T2:这题跪了一次.样例太有误导性,严重差评.题意是 询问在时间$[x,y]$内海浪高度第$K$小的单位时刻是那个时刻. 但由于样例太弱,错以为是 询问在时间$[x,y]$内海浪高度第$K$小的海浪高度值. 除了这个问题,别的都很简单了,抽出

[NOIP集训]10月18日

今天的文件夹:10月18日.zip 今天脑子转不起来,想不出来动规了. Orz @张翰文学神 T1:快排,然后求连续数字的长度,简单判断即可. T2~T4:容我再想两天... T2原题: 题2. 养zsc(pig.pas/c/cpp) [题目描述] 你有一个zsc圈,有N头zsc,每天你最多可以杀一头zsc卖钱,获益就是zsc的体重.但是每过一天每头zsc的体重都会下降P[i](当然,如果zsc体重<=0了,自然获利就是0),问K天内你的最大获利. [输人文件] 第一行两个数N.K: 第二行N个