#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+10;
int dp[maxn][maxn], is[maxn];//动态规划数组和判断是否取用的数组
int w[maxn], v[maxn], V, n;//体积数组,价值数组,背包最大容量,物品件数
void Dp(){//动态规划函数
for(int i = 1; i <= n; i++){
for(int j = 1; j <= V; j++){//从背包剩余容量大于该物品时开始取用
if(j < w[i]) dp[i][j] = dp[i-1][j];//背包剩余容量小于物品体积,不取,体积等于取到i-1时的体积
else dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//此时的最大容量等于不取用该物品(dp[i-1][j])或者取用该物品(dp[i-1)[j-w[i]]+v[i]);
}
}
}
void Init(){
memset(is, 0, sizeof is);//初始化表示最初每件物品都不取
printf("请输入每件物品的价值和体积\n");
for(int i = 1; i <= n; i++)
scanf("%d%d", &v[i], &w[i]);
memset(dp,0,sizeof dp);//每件物品都不取用价值都为零
}
void f()
{
int c = V;
for(int i = n; i >= 1; i--)
{
if(dp[i][c]==dp[i-1][c])
{
is[i] = 0;
}
else {
is[i] = 1;
c-=w[i];
}
}
}
void Print(){
printf("背包表格如下:\n");
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <= V; j++){
if(j)printf(" ");
printf("%d",dp[i][j]);
}
printf("\n");
}
printf("最大价值是%d\n",dp[n][V]);
printf("最佳选择为\n");
f();
for(int i = 1; i <= n; i++){
if(is[i])printf("%d ",i);
}
printf("\n");
}
int main()
{
printf("请输入物品件数和背包容量,物品为负时输入截止\n");
while(~scanf("%d%d", &n, &V)&&n>=0)
{
Init();//初始化
Dp();//动态规划
Print();//输出
}
}
/*
4 8
3 2
4 3
5 4
6 5
5 10
6 2
3 2
5 6
4 5
6 4
*/