E. Money Buys Happiness
题意:给你\(m\)个月,每个月可以赚\(x\)元, 每个月你都有一次机会花费\(c_i\)元, 获得\(h_i\)的幸福。(当然你目前得有足够的钱)。 求出能够获得的最大幸福值。
思路:我们可以求出获得\(i\)幸福值所需的最小花费,然后判断能否有足够的钱即可。考虑如何求解, 把花费\(c_i\)看成物品价值,把\(h_i\)看成物品体积。那么容易发现,这个问题是一个\(01\)背包问题。那么状态转移就可以得到
f[j]=min(f[j],f[j-h[i]]+w[i])
代码
// Problem: E. Money Buys Happiness
// Contest: Codeforces - Codeforces Round 946 (Div. 3)
// URL: https://codeforces.com/contest/1974/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
using ll=long long;
using i128=__int128;
typedef unsigned long long ull;
typedef pair<int, int> Pii;
const int Inf=0x3f3f3f3f;
void solve()
{
ll m,x;cin>>m>>x;
vector<ll>c(m+1),h(m+1);
int ans=0;
int sum=0;
for(int i=1;i<=m;i++)
{
cin>>c[i]>>h[i];
sum+=h[i];
}
vector<ll>f(sum+1,1e18);
f[0]=0;
for(int i=1;i<=m;i++)
for(int j=sum;j>=h[i];j--)
{
if(f[j-h[i]]+c[i]<=(i-1)*x)
f[j]=min(f[j],f[j-h[i]]+c[i]);
}
for(int i=sum;i>=0;i--)
{
if(f[i]<=(m-1)*x)
{
cout<<i<<endl;
return;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _=1;cin>>_;while(_--)solve();
return 0;
}
标签:946,Codeforces,long,int,using,Div,Round
From: https://www.cnblogs.com/Shumian/p/18460678