这道题关于字典序为什么要逆序,还有如何记录状态路径做了示范,是一道非常有启发的题目。
还有就是贪心可以做,但是做不出字典序的效果
a 1 1 1 b 1 2 1 c 1 1 1
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node
{
string s;
int d,c;
};
struct rcr
{
int value=0,pre=0,now=0,time=0;
};
void printans(vector<rcr> dp,int n,vector<node> sbj)
{
if(dp[n].pre)
printans(dp,dp[n].pre,sbj);
cout<<sbj[dp[n].now].s<<'\n';
}
int main()
{
//ios::sync_with_stdio(false);
int t;cin>>t;
while(t--)
{
int n;cin>>n;
vector<node> sbj(n+1);
for(int i=0;i<n;i++)
cin>>sbj[i].s>>sbj[i].d>>sbj[i].c;
vector<rcr> dp(1<<n);
for(int i=1;i<(1<<n);i++)
{
dp[i].value=0x3f3f3f3f;
for(int j=n-1;j>=0;j--)
{
int tmp=1<<j;
if(i&tmp)
{
int f=i-tmp;
if(dp[i].value>dp[f].value+max(dp[f].time+sbj[j].c-sbj[j].d,0))
{
dp[i].value=dp[f].value+max(dp[f].time+sbj[j].c-sbj[j].d,0);
dp[i].time=dp[f].time+sbj[j].c;
dp[i].pre=f;
dp[i].now=j;
}
}
}
}
cout<<dp[(1<<n)-1].value<<'\n';
printans(dp,(1<<n)-1,sbj);
}
return 0;
}