- 朴素方法
public int bag01( int[] weight , int[] value , int capacity )
{
int length = weight.length;
int[][] dp = new int[length+1][capacity+1];
for( int i=1 ; i<=length ; i++ )
for( int j=1 ; j<=capacity ; j++ )
{
dp[i][j] = dp[i-1][j];
if( j>=weight[i-1] )
dp[i][j] = Math.max( dp[i][j] , dp[i-1][j-weight[i-1]]+value[(i-1)] );
}
return dp[length][capacity];
}
-
滚动数组
某行的状态只与上一行的状态相关
public int bag02( int[] weight , int[] value , int capacity )
{
int length = weight.length;
int[][] dp = new int[2][capacity+1];
for( int i=1 ; i<=length ; i++ )
for( int j=1 ; j<=capacity ; j++ )
{
dp[i&1][j] = dp[(i-1)&1][j];
if( j>=weight[i-1] )
dp[i&1][j] = Math.max( dp[i&1][j] , dp[(i-1)&1][j-weight[i-1]]+value[(i-1)] );
}
return dp[length&1][capacity];
}
-
一维数组
某个状态只与上一行相同位置以及上一行左侧位置状态相关(与上文两种算法不同的是,这里枚举某一行的状态时要从后向前枚举)
public int bag03( int[] weight , int[] value , int capacity )
{
int length = weight.length;
int[] dp = new int[capacity+1];
for( int i=1 ; i<=length ; i++ )
for( int j=capacity ; j>=weight[i-1] ; j-- )
{
if( j>=weight[i-1] )
dp[j] = Math.max( dp[j] , dp[j-weight[i-1]] + value[i-1] );
}
return dp[capacity];
}