【HDOJ】3732 Ahui Writes Word

初看01背包,果断TLE。是因为n和C都比较大。但是vi和ci却很小,转化为多重背包。

 1 #include <cstdio>
 2 #include <cstring>
 3
 4 int map[15][15];
 5 int dp[10005];
 6 int n, C;
 7
 8 int max(int a, int b) {
 9     return a>b ? a:b;
10 }
11
12 void ZeroOnePack(int v, int c) {
13     for (int i=C; i>=c; --i)
14         dp[i] = max(dp[i-c]+v, dp[i]);
15 }
16
17 void CompeletePack(int v, int c) {
18     for (int i=c; i<=C; ++i)
19         dp[i] = max(dp[i-c]+v, dp[i]);
20 }
21
22 void MultiPack(int v, int c, int k) {
23     if (c*k >= C) {
24         CompeletePack(v, c);
25         return ;
26     }
27     int r = 1;
28     while (r < k) {
29         ZeroOnePack(r*v, r*c);
30         k = k - r;
31         r <<= 1;
32     }
33     ZeroOnePack(k*v, k*c);
34 }
35
36 int main() {
37     int v, c;
38     char s[15];
39     int i, j;
40
41     while (scanf("%d %d", &n, &C) != EOF) {
42         memset(map, 0, sizeof(map));
43         memset(dp, 0, sizeof(dp));
44         for (i=0; i<n; ++i) {
45             scanf("%s %d %d", s, &v, &c);
46             map[v][c]++;
47         }
48         for (i=1; i<=10; ++i) {
49             for (j=0; j<=10; ++j) {
50                 if (map[i][j])
51                     MultiPack(i, j, map[i][j]);
52             }
53         }
54         printf("%d\n", dp[C]);
55     }
56
57     return 0;
58 }
时间: 2024-10-08 09:04:12

【HDOJ】3732 Ahui Writes Word的相关文章

【背包专题】F - Ahui Writes Word hdu3732【01背包+二进制优化】

We all know that English is very important, so Ahui strive for this in order to learn more English words. To know that word has its value and complexity of writing (the length of each word does not exceed 10 by only lowercase letters), Ahui wrote the

HDU 3732 Ahui Writes Word(多重背包)

http://acm.hdu.edu.cn/showproblem.php?pid=3732 题意: 初始有N个物品, 每个物品有cost[i]花费和val[i]价值, 你有m元钱, 现在问你最多能买多少总价值的物品? 其中N<=10W, m<=1W. 且cost[i]和val[i]都在[0,10]范围. 分析: 本题初看直接用01背包来做是直观的想法. 但是考虑到01背包的复杂度为O(N*m), 这么大的复杂度肯定不行. 然后我们发现其实每种物品只与它的cost[i]和val[i]有关, 如

HDU 3732 Ahui Writes Word

乍一看是01背包,但是100000*10000的复杂度肯定是TLE的,但是(0 ≤ Vi , Ci ≤ 10),所以最多也只有100种物品,转化成多重背包去做. #include<cstdio> #include<cstring> #include<cmath> int N,C,vv,cc; int g[15][15]; char s[100]; int w[105],c[105],n1[105]; int tot; int f[10000+10]; int max(i

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t