• A


    题目链接:http://poj.org/problem?id=3624

    题意:

    经典0—1背包问题,有n个物品,编号为i的物品的重量为w[i],价值为v[i],现在要从这些物品中选一些物品装到一个容量为m的背包中,使得背包内物体在总重量不超过m的前提下价值尽量大. 其中dp[i,j]表示的是前i个物品装入容量为j的背包里所能产生的最大价值,w[i]是第i个物品的重量,d[i]是第i个物品的价值。如果某物品超过背包容量,则该物品一定不放入背包,问题变为剩余i-1个物品装入容量为j的背包所能产生的最大价值;否则该物品装入背包,问题变为剩余i-1个物品装入容量为j-w[i]的背包所能产生的最大价值加上物品i的价值d[i]

    这道题一开始是用二维数组写的,后来发现这道题的m有点大,二维数组开不了那么大,改用一维。

    用此时的i行的数据来覆盖i-1行的。

    但是要逆序 j从m到w[i],以j=m.0的顺序推f[j],这样才能保证推f[j]时f[j-c[i]]保存的是状态f[i-1][j-c[i]]的值。

    如果将j的循环顺序从上面的逆序改成顺序的话,那么则成了f[i][j]由f[i][j-c[i]]推知,与本题意不符。




    #include<iostream> #include<cstring> #include<stdio.h> #include<math.h> #include<algorithm> using namespace std; const int maxn=10200; #define N 14010 int n,m; int f[N]; int w[N]; int d[N]; int main() { int a,b,c,m; while(~scanf("%d%d",&n,&m)) { memset(w,0,sizeof(w)); memset(d,0,sizeof(d)); memset(f,0,sizeof(f)); for(int i=1; i<=n; i++) scanf("%d%d",&w[i],&d[i]); for(int i=1; i<=n; i++) for(int j=m; j>=w[i]; j--)///当此时的j小于此时的w[i]时,循环不再进行下去 f[j] = max(f[j],f[j-w[i]]+d[i]); ///与i-1时的f[j]来与i-1时的f[j减去此时w[i]]加上此时的d[i]比较; printf("%d ",f[m]); } return 0; }
  • 相关阅读:
    Warsaw University Contest Petrozavodsk, Thursday, January 31, 2008 J题,Gym100096J
    FZU2282--错排公式
    POJ 3468 区间加减 区间求和
    HDU 1556 树状数组
    HDU 5480 树状数组
    Tomcat
    Nginx
    Centos7安装后无法联网
    限制服务器ssh登录及防御措施
    DHCP
  • 原文地址:https://www.cnblogs.com/biu-biu-biu-/p/5735618.html
Copyright © 2020-2023  润新知