#include<iostream>
using namespace std;
/**
整数切分。比如2有1种1+1
3有2种 1+1+1 2+1
4有4种 1+1+1+1 2+2 1+3 1+1+2
5有6种 1+1+1+1+1 1+1+3 1+1+1+2 2+2+1 2+3 1+4
*/
int IntergeSplit(int n)
{
if (n <= 1)
return 0;
int **dp = new int*[n+1];
for(int i = 0; i <= n;++i)
dp[i] = new int[n+1];
dp[0][0] = 1;
for(i = 1; i <= n;++i)
dp[i][0] = 0;
for(int j = 1; j <= n;++j)
dp[0][j] = 0;
for(i = 1; i <= n; ++i)
{
for(j = 1; j <= n;++j)
{
dp[i][j] = 0;
for(int k = 0; k <= j; ++k)
{
if( k > i-j )
break;
dp[i][j] += dp[i-j][k];
}
/*
int number_j = i/j; //在整数i的切分里,最多有number_j个 j
for(int k = 1; k <= number_j; ++k)
// dp[i][j] += dp[i-k*j][j];
for(int m = 0; m < j; ++m)
dp[i][j] += dp[i-k*j][m];
*/
}
}
int result = 0;
for(j = 1; j <= n; ++j)
result += dp[n][j];
for(i = 0; i<= n;++i)
delete []dp[i];
delete []dp;
// delete []*dp;
// delete []dp;
return result - 1;
}
//0-1背包问题
int max(int a,int b)
{
return a > b?a:b;
}
void Packet0_1(int W,int w[],int value[],unsigned int length)
{
if(W == 0)
return;
int **dp = new int*[length+1];
for(int i = 0; i <= length; ++i)
dp[i] = new int[W+1];
for(i = 0; i <= length; ++i)
dp[i][0] = 0;
for(i = 0; i <= W; ++i)
dp[0][i] = 0;
//j 是当前背包容量
//i 是当前可选的前i个物品
for(i = 1; i <= length; ++i)
{
for(int j = 1; j <= W; ++j)
{
//当前容量是否能放下物品j
//w[]下标从0开始,因此都要i-1,value[]也是如此
if( j >= w[i-1])
{
//看加入物品i与不加入物品i,哪个价值大。
dp[i][j] = max(dp[i-1][j-w[i-1]]+value[i-1],dp[i-1][j]);
}
else
dp[i][j] = dp[i-1][j];
}
}
cout<<dp[length][W]<<endl;
for(i = 0; i <=length; ++i)
delete [] dp[i];
delete []dp;
}
void main()
{
/*
for(int i = 0; i <= 20; i++)
cout<<i<<" "<<IntergeSplit(i)<<endl;
*/
int w[] = {3,4,5,6,10};
int v[] = {1,2,4,3,5};
int len = sizeof(w)/sizeof(int);
Packet0_1(10,w,v,len);
}