zoukankan      html  css  js  c++  java
  • 0-1背包再修改版

    题目描述

    把钱花完了,所以单身了,单身了所以过双“11”,过双“11”所以把钱花完了。

    今年Nova君(三号)照旧过着他暗无天日的“买买买”的双“11”,然而因为囊中羞涩,并不能够太任性。他的购物车中,列满了数不清的商品,共有N件,好多商品居然还不止一件 __(:3 」∠)_ 现在Nova君要做出一个艰难的抉择,他要从所有商品中挑出m件拼成一个订单,请问有多少种凑单的方法呢?求访法数对M的余数。

    PS:同一种商品不作区分。

    输入

    多组测试数据(不超过100组)

    每组数据两行,第一行为三个正整数N,m,M,具体意义详见描述,第二行为N个正整数a1,a2,,,an,代表第i个商品的个数

    (1<=N,ai,m<=1000,2<=M<=10000)

    输出

    对于每组数据,输出一行,表示方法总数

    输入样例

    3 3 10000
    1 2 3

    输出样例

    6

    题目来源:http://biancheng.love/contest/17/problem/G/index
    详情见代码以及注释:
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 const int N=1010;
     5 int a[N];
     6 int b[N][N];
     7 int main()
     8 {
     9     int n,m,M;
    10     while(scanf("%d%d%d",&n,&m,&M)==3)
    11     {
    12         for(int i = 0; i < n; i++)
    13             scanf("%d",&a[i]);//每种商品的件数
    14 
    15         for(int i = 0; i <= n; i++)
    16             b[i][0] = 1;
    17 
    18         for(int i = 0; i < n; i++)//n种商品
    19             for(int j = 1; j <= m; j++)//挑出m件
    20             {
    21                 if(j -1 - a[i] >= 0)//是否大于第i中商品件数
    22                     b[i+1][j] = (b[i][j] + b[i+1][j-1] - b[i][j-1-a[i]] +M)%M;
    23                 else
    24                     b[i+1][j] = (b[i][j] + b[i+1][j-1])%M;
    25             }
    26         printf("%d
    ",b[n][m]);
    27     }
    28 
    29 }
    另附背包的一些模板函数:
     1 void ZoreOnePack(int cost , int weight)//0-1背包
     2 {
     3     for (int i = W ; i >= weight ; -- i)
     4         f[i] = max(f[i],f[i-weight]+cost) ;
     5 }
     6 
     7 void CompletePack(int cost , int weight)//完全背包
     8 {
     9     for (int i = weight ; i <= W ; ++ i)
    10         f[i] = max(f[i],f[i-weight]+cost) ;
    11 }
    12 
    13 void MultiPack(int cost , int weight , int num)//多重背包
    14 {
    15     if (num*weight>=W)
    16         CompletePack(cost,weight) ;
    17     else
    18     {
    19         int k = 1 ;
    20         while (k<num)
    21         {
    22             ZoreOnePack(cost*k,weight*k) ;
    23             num -= k ;
    24             k += k ;
    25         }
    26         ZoreOnePack(cost*num,weight*num) ;
    27     }
    28 }
    29 
    30 void TwoZoreOnePack(int cost , int weight , int many)
    31 {
    32     for (int i = W ; i >= weight ; -- i)
    33         for (int j = M ; j >= many ; -- j)
    34             two[i][j] = max(two[i][j],two[i-weight][j-many]+cost) ;
    35 }
    36 
    37 void TwoCompletePack(int cost ,int weight ,int many)
    38 {
    39     for (int i = weight ; i <= W ; ++ i)
    40         for (int j = many ; j <= W ; ++ j)
    41             two[i][j] = max(two[i][j],two[i-weight][j-many]+cost) ;
    42 }
    43 
    44 void TwoMultiPack(int cost ,int weight , int many , int num)
    45 {
    46     if (num*weight>=W&&num*many>=M)
    47         TwoCompletePack(cost,weight,many) ;
    48     else
    49     {
    50         int k = 1 ;
    51         while (k<num)
    52         {
    53             TwoZoreOnePack(cost*k,weight*k,many*k) ;
    54             num -= k ;
    55             k += k ;
    56         }
    57         TwoZoreOnePack(cost*num,weight*num,many*num) ;
    58     }
    59 }
    
    
    


     
  • 相关阅读:
    windows ip路由
    linux ip命令和ifconfig命令
    工作项目技术总结
    网络安全体系
    网络适配器输入的IP地址 已经分配给另一个适配器
    Android笔记之ImageView设置图片以灰色显示
    js小功能
    html2canvas截取图片跨域解决办法
    JS学习笔记(二).eq()与[]的区别
    jQuery中常用的元素查找方法总结
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/4966387.html
Copyright © 2011-2022 走看看