离NOIP2018越来越近了,然而我仍有一些没有彻底弄懂的地方,有点慌,所以准备从这周开搞搞基础。

  不说别的了,先把这篇总结写完。

 

  Day1的题感觉不是很难,每一道题的暴力也都可写,总的来说难度跟noip差不多吧。

  有一个想吐槽的地方,就是为啥题目把算法都告诉了……

T1 backpack

  期望得分:100

  实际得分:100

  正像题解所说,Day1T1是送分的。不过辛亏我以前做过一道类似的题,要不然只能得60。

  首先40分是送的,完全背包板子。然后发现尽管物品很多,但是体积和价值只有100。所以如果两件物品体积相同,那么就取价值更大的。所以实际上物品最多只有100个。然后一个O(100 * n)就得了60分。

  正解其实我也不知道为啥,不过以前做过一道搜索题,那道题数据范围特别大,但是除了暴力我实在想不出来该咋办,然后看题解时记住了这么一句话:“远距离贪心,近距离暴力”。到了这道题,就变成了“大容量贪心,小容量背包”。于是我们用性价比最高的物品填背包,直到剩余容量在1e5范围内,然后正常完全背包了。

考场代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const int maxm = 1e5 + 5;
21 inline ll read()
22 {
23     ll ans = 0;
24     char ch = getchar(), last = ' ';
25     while(!isdigit(ch)) {last = ch; ch = getchar();}
26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
27     if(last == '-') ans = -ans;
28     return ans;
29 }
30 inline void write(ll x)
31 {
32     if(x < 0) x = -x, putchar('-');
33     if(x >= 10) write(x / 10);
34     putchar(x % 10 + '0');
35 }
36 void MYFILE()
37 {
38 #ifndef mrclr
39     freopen("backpack.in", "r", stdin);
40     freopen("backpack.out", "w", stdout);
41 #endif
42 }
43 
44 int n;
45 ll m;
46 ll dp[maxm];
47 int t[105];
48 
49 void work0()
50 {
51     ll ans = 0;
52     int pos = 1;
53     for(int i = 1; i <= 100; ++i) if((ll)t[i] * (ll)pos > (ll)t[pos] * (ll)i) pos = i;
54     ll x = (m - maxm + (ll)pos - 1) / (ll)pos;
55     m -= x * (ll)pos;
56     ans += x * (ll)t[pos];    
57 //    printf("@%lld\n", ans);
58     for(int i = 1; i <= 100; ++i)
59         for(int j = i; j <= m; ++j)
60             dp[j] = max(dp[j], dp[j - i] + t[i]);
61     write(dp[m] + ans), enter;
62 }
63 
64 int main()
65 {
66     MYFILE();
67     n = read(); m = read();
68     for(int i = 1; i <= n; ++i)
69     {
70         int x = read(), y = read();
71         t[x] = max(t[x], y);
72     }
73     if(m > maxm) {work0(); return 0;}
74     for(int i = 1; i <= 100; ++i)
75         for(int j = i; j <= m; ++j)
76             dp[j] = max(dp[j], dp[j - i] + t[i]);
77 //    for(int j = 1; j <= m; ++j) printf("%lld ", dp[j]); enter;
78     write(dp[m]), enter;
79     return 0;
80 }
81 /*
82 2 15
83 3 2
84 5 3
85 */
View Code

相关文章: