离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 */