• 洛谷P1858


    ({mathcal{For}}) ({mathcal{we} })({mathcal{live} })({mathcal{by} })({mathcal{faith} })({mathcal{,} })({mathcal{not} })({mathcal{by} })({mathcal{sight} })({mathcal{.}})


    Description

    N 种物品,有各自的价值 w 和代价 c;

    一个背包,容量为 V;

    背包内同样类型的物体只能装一个;

    求 K 种不同的方法,使得背包在被装满的情况下价值和最大。


    Analysis

    01背包问题最 k 优解问题;

    先考虑如何求最大解,运用 01 背包基础思想解决;

    (f[i]) 表示当前背包装第 i 件物品的最大价值;

    [f[v]=max(f[v],f[v-cost]+weight) ]

    但显然这并不能满足这个题的需要

    那~

    • 开一个二维数组 (f[i][j]) 表示背包容量为 i 时的第 j 优解;

    • 开两个变量 Yes 和 No 储存表示体积为 v 和 v - c[ ] 时的最优解;

    • 开一个数组 Ans[ ] 来暂时存储答案;

    • 开一个变量 cnt 记录当前是第 cnt 优解

    方程式这里不好描述 ,具体见代码;


    Code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define maxn 2000100
    #define maxm 4010
    #define INF 0x3f3f3f3f
    #define Init1(s) memset(s,0,sizeof s)
    #define Init2(s) memset(s,INF,sizeof s)
    #define Init3(s) memset(s,-INF,sizeof s)
    
    using namespace std;
    
    int k,v,n,w[maxn],c[maxn];
    int f[maxm<<1][50];
    int Res;
    int Ans[maxm];
    int cnt,Yes,No;
    
    int read() {
    	int s=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
    	return s*w;
    }
    
    void Pack01(int cost,int weight) {
    	for(int i=v; i>=weight; i--) {
    		Yes=1;No=1;cnt=0;
    		while(cnt<=k) {
    			if(f[i][Yes]>f[i-weight][No]+cost) Ans[++cnt]=f[i][Yes++];
    			else Ans[++cnt]=f[i-weight][No++]+cost;
    		}
    		for(int j=1; j<=k; j++) f[i][j]=Ans[j];
    	}
    }
    
    int main() {
    	Init3(f);
    	f[0][1]=0;
    	k=read(),v=read(),n=read();
    	for(int i=1; i<=n; i++) {
    		w[i]=read();
    		c[i]=read();
    		Pack01(c[i],w[i]);
    	}
    	
    	for(int i=1; i<=k; i++) Res+=f[v][i];
    	printf("%d
    ",Res);
    	return 0;
    }
    

  • 相关阅读:
    windows 下安装securecrt 绿色版
    对Linux命令进一步学习vim(二)
    提高php编程效率的小结
    javaScript 的小技巧
    常用 Git 命令文档和命令
    你 get 了无数技能,为什么一事无成
    Ubuntu14.4下安装FTP
    对Linux命令进一步学习
    可以输入也可以下拉选择的select
    APP接口基础学习一
  • 原文地址:https://www.cnblogs.com/KnightL/p/13935242.html
Copyright © 2020-2023  润新知