• (01背包)HDU


    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126


    题意:给n个物品,和m块钱,输出最多物品个数和其方案数。


    委屈:求出最多物品个数就是一个裸的01背包,但是同时求出方案数,难住了我。

    想了半天,感觉可以一波dp求出来,但是又想不明白状态是怎么表示和转移的。

    无奈就先写个dfs提交试一发,果断超时了。

    最后无奈看了题解,只能说,01背包还是不会。

    其实与其说01背包不会不如说动态规划不会,感觉好难。

    感觉自己好lowbee啊。。

    感觉碰到dp就萎了。

    1、想不出状态转移方程

    2、搞不清循环的顺序

    3、定不了正确的边界

    好垃圾啊我。。


    分析:在dp上加一维,dp[][0]表示原本的背包,dp[][1]表示方案个数。

    把每个物品的价值看成1。

    当当前的物品选择取时:

    如果总价值和不取一样多,说明两种不同的总花费得到了相同的价值,这个时候,方案数应该想加起来。

    if (dp[j][0]==dp[j-cost[i]][0]+1)  
           dp[j][1]=dp[j-cost[i]][1]+dp[j][1];  

    如果总价值比不取多,说明在原总价值的基础上产生了新的花费方案,但是这些方案继承于取前的方案,所以方案数不变。

    1 else if (dp[j][0] < dp[j-cost[i]][0]+1)  {  
    2      dp[j][0]=dp[j-cost[i]][0]+1;  
    3      dp[j][1]=dp[j-cost[i]][1];  
    4 } 

    代码:

     1 #include <set>
     2 #include <map>
     3 #include <list>
     4 #include <cmath>
     5 #include <queue>
     6 #include <vector>
     7 #include <bitset>
     8 #include <string>
     9 #include <cctype>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <iostream>
    14 #include <algorithm>
    15 
    16 using namespace std;
    17 
    18 typedef long long ll;
    19 typedef unsigned long long ull;
    20 #define inf (0x3f3f3f3f)
    21 #define lnf (0x3f3f3f3f3f3f3f3f)
    22 #define eps (1e-8)
    23 int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    24 
    25 //--------------------------
    26 
    27 int t;
    28 int cost[40];
    29 int dp[510][2];
    30 int n,m;
    31 
    32 void solve(){
    33     scanf("%d",&t);
    34     while(t--){
    35         scanf("%d%d",&n,&m);
    36         for(int i=0;i<n;i++){
    37             scanf("%d",&cost[i]);
    38         }
    39         memset(dp,0,sizeof(dp));
    40         for(int i=0;i<=m;i++){
    41             dp[i][1]=1;
    42         }
    43         for(int i=0;i<n;i++){
    44             for(int j=m;j>=cost[i];j--){
    45                 if (dp[j][0]==dp[j-cost[i]][0]+1)  
    46                     dp[j][1]=dp[j-cost[i]][1]+dp[j][1];  
    47                 else if (dp[j][0] < dp[j-cost[i]][0]+1)  {  
    48                     dp[j][0]=dp[j-cost[i]][0]+1;  
    49                     dp[j][1]=dp[j-cost[i]][1];  
    50                 } 
    51             }
    52         }
    53         if(dp[m][0]==0)puts("Sorry, you can't buy anything.");
    54         else printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.
    ",dp[m][1],dp[m][0]);
    55     }    
    56 }
    57 
    58 
    59 
    60 
    61 
    62 int main() {
    63 
    64 #ifndef ONLINE_JUDGE
    65     freopen("in.txt", "r", stdin);
    66     //freopen("out.txt", "w", stdout);
    67 #endif
    68     //iostream::sync_with_stdio(false);
    69     solve();
    70     return 0;
    71 }
  • 相关阅读:
    前端性能优化(css动画篇)
    常用的布局及技巧
    一些有用的技能点
    做webApp遇到的一些坑及解决方案
    mysql5.7.30 编译安装
    windows使用Pandoc将Markdown转换为PDF文件
    源码编译安装keepalived
    源码编译php
    源码编译nginx
    源码编译PHP提示zip错误
  • 原文地址:https://www.cnblogs.com/tak-fate/p/5894753.html
Copyright © 2020-2023  润新知