1 5 10 1 2 3 4 5 5 4 3 2 1
14
0/1 背包的典型应用,不过对于数据还是要注意点,因为骨头的体积可以是零。
具体的状态转移方程:
f [ i ][ v ] = max ( f[ i - 1] [ v - v[ i ] ] + w[ i ], f[ i - 1] [ v ])
也可以用一维数组
f[ v ] = max( f[ v ], f[v - v[ i ]] + w[ i ])
一维的要从v -> 0 循环,二维的就是 0 -> v循环
然后注意下menset 就差不多了。
最近开始狠抓 dp 所以 一步一步的努力学好,一点一点积累 加油!
贴个二维代码 :
#include <stdio.h> #include <string.h> #define N 1010 int dp[N][N]; int value[N]; int V[N]; int max(int a,int b){ return a > b ? a : b; } int main() { int i,n,v,t,j; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&v); for(i = 1; i <= n; i++){ scanf("%d",&value[i]); } for(i = 1; i <= n; i++){ scanf("%d",&V[i]); } memset(dp,0,sizeof(dp)); for(i = 1; i <= n; i++){ for(j = 0; j <= v ; j++){ if(j >= V[i]) dp[i][j] = max(dp[i - 1][ j - V[i]] + value[i],dp[i-1][j]); else dp[i][j] = dp[i - 1][j]; } } printf("%d\n",dp[n][v]); } return 0; }
一维代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define eps 10e-8 const int MAX_ = 1010; const int N = 100010; const int INF = 0x7fffffff; struct node{ int value, v; }a[MAX_]; int dp[MAX_]; int n, m; int main(){ int s, t, v, T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); mst(dp,0); for(int i = 1; i <= n; ++i){ scanf("%d",&a[i].value); } for(int i = 1; i <= n; ++i){ scanf("%d",&a[i].v); } for(int i = 1; i <= n; ++i){ for(int j = m; j >= a[i].v; --j){ dp[j] = max(dp[j], dp[j - a[i].v] + a[i].value); } } printf("%d\n",dp[m]); } return 0; }