1 条题解
-
0
【参考程序】
01背包问题:如题,01指的是每个物品有选(1状态)和不选(0状态)两种状态,最后得到f数组。
数据结构: bool f[]:f[i]等于True表示有办法选若干个物品使其总重量为i(即:i可以被填满) 算法分析与过程: 1、矛盾:不知道怎么选物品,也不知道选多少个。01背包算法很好解决这两个问题。 2、算法过程: (1)、物品逐个填f数组(让f数组的某些格子变成True),而且从大往小填 for(int j=v;j>=a[i];j--) (2)、对于某个j,此时的f[j]是没有a[i]的影响的,如果 f[ j-a[i] ]==1,那么f[j]就可以填(等于1) 有的同学会疑问:例如样例,有6 9 9 12 12 15 20。一开始,6先来填,它只让f[6]等于1,6表示不服气:它觉得它自己还能填更多的f,比如6+15可以让f[21]等于1。 我们可以安慰6:以后轮到15来填,15看到f[6]等于1,它就能让f[21]等于1。#include <bits/stdc++.h> using namespace std; int a[30]; bool f[20001]; int main() { int v, n; scanf("%d%d", &v, &n); for(int i=1; i<=n; i++) scanf("%d", &a[i]); memset(f, 0, sizeof(f)); f[0] = 1; for(int i=1; i<=n; i++) { for(int j=v; j>=a[i]; j--) { if(f[j - a[i]] == 1) { f[j] = 1; } } } int p; for(int i=v; i>=0; i--) // 从大到小找到第一个为True的f值 { if(f[i] == 1) { p = i; break; } } printf("%d\n", v - p); return 0; }
- 1
信息
- ID
- 96
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- 递交数
- 605
- 已通过
- 121
- 上传者