P8903 [USACO22DEC] Bribing Friends G
暴力 dp 是简单的。
实际上的消费情况按 \(X_i\) 从小到大排序,为存在中转点 \(i\),\([1,i)\) 均用甜筒,\((i,n]\) 均用哞尼,\(i\) 用若干甜筒 + 若干哞尼。
假设在 \((i,n]\) 用了 \(x\) 个甜筒换了 \(c\) 哞尼而 \([1,i)\) 用了 \(y\) 哞尼,那么这 \(x\) 个甜筒拿到 \([1,i)\) 换到的哞尼数 \(c'\) 必定不小于 \(c\),再拿换到的哞尼换出那 \(y\) 哞尼扔到后面,这样显然不劣。
于是只需要求出 \(f_{i,j},g_{i,j}\) 分别表示前缀 \(i\) 用 \(j\) 甜筒 / 后缀 \(i\) 用 \(j\) 哞尼能得到的最大欢迎度。
统计答案时枚举中转点 \(i\) 以及 \(i\) 用了多少哞尼直接合并对应的 \(f,g\) 状态即可。
#include<bits/stdc++.h>
#define fin(x) freopen(#x".in","r",stdin)
#define fout(x) freopen(#x".out","w",stdout)
#define fr(x) fin(x),fout(x);
#define Fr(x,y) fin(x),fout(y)
#define INPUT(_1,_2,FILE,...) FILE
#define IO(...) INPUT(__VA_ARGS__,Fr,fr)(__VA_ARGS__)
using namespace std;
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define ull unsigned long long
#define intz(x,y) memset((x),(y),sizeof((x)))
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define tup(x) array<int,(x)>
inline ll read(){
ll x=0,f=1;char ch=nc();
while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}
while(ch>=48&&ch<=57)x=x*10+ch-48,ch=nc();
return x*f;
}
//void write(int x){cout<<x<<' ';}
//void write(pii x){cout<<"P("<<x.fi<<','<<x.se<<")\n";}
//void write(vector<auto>x){for(auto i:x)write(i);cout<<'\n';}
//void write(auto *a,int l,int r){for(int i=l;i<=r;i++)write(a[i]);cout<<'\n';}
inline ll lowbit(ll x){return x&-x;}
inline int pcount(ll x){
for(int i=0,res=0;;res+=(x>>i)&1,i++)
if(i>60)return res;
}
//struct mt{
// ll v;
// mt(){v=0;}
// mt(int x){this->v=x;}
// inline mt operator+(mt x){return {(v+x.v)%mod};}
// inline mt operator-(mt x){return {(v+mod-x.v)%mod};}
// inline mt operator*(mt x){return {1ll*v*x.v%mod};}
//};
//mt qp(mt x,int y){mt res(1);for(;y;x=x*x,y>>=1)if(y&1)res=res*x;return res;}
const int N=2005;
struct node{int x,y,z;}a[N];
int f[N][N],g[N][N];
inline void UesugiErii(){
int n,A,B;cin>>n>>A>>B;
for(int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y>>a[i].z;
sort(a+1,a+1+n,[](node x,node y){return x.z<y.z;});
for(int i=1;i<=n;i++)
for(int j=0;j<=B;j++){
f[i][j]=f[i-1][j];
if(j>=a[i].y*a[i].z)
f[i][j]=max(f[i][j],f[i-1][j-a[i].y*a[i].z]+a[i].x);
}
for(int i=n;i;i--)
for(int j=0;j<=A;j++){
g[i][j]=g[i+1][j];
if(j>=a[i].y)
g[i][j]=max(g[i][j],g[i+1][j-a[i].y]+a[i].x);
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=min(a[i].y,A);j++)
if((a[i].y-j)*a[i].z<=B)
ans=max(ans,f[i-1][B-(a[i].y-j)*a[i].z]+a[i].x+g[i+1][A-j]);
cout<<ans;
}
signed main(){
//IO();//cfast;
int _=1;//cin>>_;
for(;_;_--)UesugiErii();
return 0;
}

浙公网安备 33010602011771号