背包问题-二进制优化
Smiling & Weeping
----不讨好所有冷漠 不辜负所有热爱
# [NOIP1996 提高组] 砝码称重
## 题目描述
设有
## 输入格式
输入方式:
(表示
## 输出格式
输出方式:`Total=N`
(
## 样例 #1
### 样例输入 #1
```
1 1 0 0 0 0
```
### 样例输出 #1
```
Total=3
```
## 提示
**【题目来源】**
NOIP 1996 提高组第四题
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int a[7] = {0,1,2,3,5,10,20} , num[10]; 5 ll dp[10010] , new_value[10010] , n , ans; 6 int main() 7 { 8 for(int i = 1; i <= 6; i++) 9 scanf("%d",&num[i]) , n += num[i]*a[i]; 10 dp[0] = 1; 11 int n_new = 0; 12 for(int i = 1; i <= 6; i++) 13 { 14 for(int j = 1; j <= num[i]; j <<= 1) 15 { 16 num[i] -= j; 17 new_value[++n_new] = j * a[i]; 18 } 19 if(num[i]) 20 { 21 new_value[++n_new] = num[i] * a[i]; 22 } 23 } 24 for(int i = 1; i <= n_new; i++) 25 for(int j = n; j >= 1; j--) 26 if(j >= new_value[i]) 27 dp[j] += dp[j - new_value[i]]; 28 for(int i = 1; i <= n; i++) 29 if(dp[i]) 30 ans++; 31 cout << "Total=" << ans << endl; 32 return 0; 33 }
其实我们可以想到,我们DP的自我滚动从n到1,是为了保证不会像dp[j+new_value[i]] += dp[j]的重复计算
我们从n到1会保证了每个只得到正确的计算次序!!!
加强理解
详见P2347 [NOIP1996 提高组] 砝码称重 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
本文作者:Smiling-Weeping
本文链接:https://www.cnblogs.com/smiling-weeping-zhr/p/17519830.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步