DP地狱训练 砝码秤重

1253: [DP地狱训练]砝码秤重 __数据加强版

时间限制: 1 Sec  内存限制: 64 MB
提交: 610  解决: 270
[提交][状态][讨论版]

题目描述

设有n种砝码,第k种砝码有Ck个,每个重量均为Wk,求:用这些砝码能秤出的不同重量的个数,但不包括一个砝码也不用的情况。

输入

输入的第一行只有一个数n,表示不同的砝码的种类数. 第2行至第n+1行,每行有两个整数.第k+1行的两个数分别表示第k种砝码的个数和重量.

输出

输出中只有一行数据:Total=N。表示用这些砝码能秤出的不同重量数。

样例输入

2 
2 2
2 3

样例输出

Total=8

提示

对于100%的数据,砝码的种类n满足:1≤n≤100;
对于30%的数据,砝码的总数量C满足:1≤C≤20;
对于100%的数据,砝码的总数量C满足:1≤C≤100;
对于所有的数据,砝码的总重量W满足:1≤W≤400000;

多重背包,把每一种重量的砝码二进制分割,然后设计dp方程表示某种重量是否能秤出。

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <vector>
 7  
 8 using namespace std;
 9  
10 int n, f[500000], c, w, ans;
11  
12 vector<int> pack;
13  
14 int main(){
15     scanf("%d", &n);
16     f[0] = 1;
17     for(int i = 1 ; i <= n ; i++){
18         scanf("%d%d", &c, &w);
19         for(int i = 1 ; i <= c ; i <<= 1){
20             pack.push_back(i * w);
21             c -= i;
22         }
23         if(c)pack.push_back(c * w);
24     }
25     for(int i = 0 ; i < pack.size() ; i ++){
26         for(int j = 450000 ; j >= pack[i] ; j --){
27             f[j] |= f[j - pack[i]];
28         }
29     }
30     for(int i = 1 ; i <= 450000 ; i ++){
31         ans += f[i];
32     }
33     printf("Total=%d\n", ans);
34 }
View Code

 

posted @ 2017-08-08 15:47  KingSann  阅读(375)  评论(0编辑  收藏  举报