思路:明显的背包dp,由于本题有“b”属性的限制,b小的物品不能从b大的状态转移过来,于是需要对b排序,先处理b小的物品。路径输出的话范围小可以用vector直接搞,也可以用数组标记一下。
①
# include <iostream>
# include <cstdio>
# include <cstring>
# include <vector>
# include <algorithm>
using namespace std;
const int maxn = 2003;
int a[maxn], b[maxn], c[maxn], dp[maxn];
int id[maxn];
vector<int>v[maxn];
bool cmp(int x, int y)
{
return b[x] < b[y];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; ++i)
scanf("%d%d%d",&a[i],&b[i],&c[i]),id[i] = i;
sort(id, id+n, cmp);
for(int k=0; k<n; ++k)
{
int i = id[k];
if(a[i]>=b[i]) continue;
for(int j=b[i]-1; j>=a[i]; --j)
{
if(dp[j-a[i]]+c[i] > dp[j])
{
dp[j] = dp[j-a[i]]+c[i];
v[j].clear();
v[j] = v[j-a[i]];
v[j].emplace_back(i);
}
}
}
int imax=0, num;
for(int i=0; i<=2000;++i)
if(dp[i] > imax)
imax = dp[i], num=i;
printf("%d\n",imax);
printf("%d\n",v[num].size());
for(auto i : v[num])
printf("%d ",i+1);
return 0;
}
②
# include <iostream>
# include <cstdio>
# include <cstring>
# include <stack>
# include <algorithm>
using namespace std;
const int maxn = 2003;
int a[maxn], b[maxn], c[maxn], dp[maxn];
int id[maxn], cho[maxn], way[103][maxn];
bool cmp(int x, int y)
{
return b[x] < b[y];
}
int main()
{
int n, imax, ans=0, num;
scanf("%d",&n);
for(int i=1; i<=n; ++i)
scanf("%d%d%d",&a[i],&b[i],&c[i]),id[i] = i;
sort(id+1, id+n+1, cmp);
for(int k=1; k<=n; ++k)
{
int i = id[k];
if(a[i]>=b[i]) continue;
for(int j=b[i]-1; j>=a[i]; --j)
{
if(dp[j-a[i]]+c[i] > dp[j])
{
dp[j] = dp[j-a[i]]+c[i];
cho[j] = i;
way[i][j] = cho[j-a[i]];
}
if(dp[j] > ans)
{
ans = dp[j];
imax = j;
num = i;
}
}
}
printf("%d\n",ans);
if(ans == 0) return 0*puts("0");
stack<int>st;
while(imax && num)
{
st.push(num);
int tmp = imax;
imax -= a[num];
num = way[num][tmp];
}
printf("%d\n",st.size());
while(!st.empty())
{
printf("%d ",st.top());
st.pop();
}
return 0;
}