题目
题解思路
在 机器分配 我们已经求过具体方案了,但是这回是要求字典序最小。
机器分配的思路就是先跑一次01背包 然后从结果往前推出答案 。
这样的思路在这题是行不通的,从后往前就很难保证是字典序最小了。
闫总之间反向跑01背包,让最大值结果在F[ 1 ][ m ] 中,然后从1开始往后面推,这样肯定可以保证字典序最小。
闫总这波逆向思维属实nb
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
int f[1010][1010];
int v[1010] , w[1010] ;
int main ()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for (int i = 1 ; i <= n ; i++ )
cin>>v[i]>>w[i];
for (int i = n ; i >= 1 ; i-- )
{
for (int j = 0 ; j <= m ; j++ )
{
f[i][j] = f[i+1][j];
if ( j >= v[i] )
{
f[i][j] = max( f[i][j] , f[i+1][ j - v[i]] + w[i] );
}
}
}
//f[1][m]是最大值
int p = m ;
for (int i = 1 ; i <= n ; i++ )
{
if ( p >= v[i] && f[i][p] == f[i+1][p - v[i]] + w[i] )
{
cout<<i<<" ";
p -= v[i];
}
}
cout<<"\n";
return 0 ;
}