♻️lzhh_lzhh32 • 3天前
#include<bits/stdc++.h>
using namespace std;
int n,m;
int dp[2][500005]; //前i个鉴定后赚的更多的物品,凑的鉴定费为j的情况下的最大所得
struct magic{
int p1,p2; //鉴定前 鉴定后
};
vector<magic> d;
int main(){
cin>>n>>m; //物品数 卷轴价格
string space; //读下空格
int bm=0; //开始时的钱数,即普通的和鉴定之后更亏的普通卖价值总和
int spz=0; //全部魔法物品普通卖的价值总和
int sp2h=0; //其余的鉴定卖的收入总和
getline(cin,space);
for(int i=1;i<=n;i++){
string s;
getline(cin,s);
if(s.find(' ')==-1){
int p=stoi(s);
bm+=p; //直接卖
}else{
int p1=stoi(s.substr(0,s.find(' ')));
int p2=stoi(s.substr(s.find(' ')+1));
if(p2<=p1+m) bm+=p1; //鉴定还亏,直接卖;
else{
d.push_back({p1,p2});
spz+=p1; //剩下物品普通卖
sp2h+=p2-m; //收入
}
}
}
if(bm+spz<=m){ //一份鉴定费都不够
cout<<bm+spz<<endl; //全部普通卖
return 0;
}
if(bm>=m){ //一开始就有钱鉴定
cout<<bm+sp2h<<endl; //全部都鉴
return 0;
}
memset(dp,0xf0,sizeof dp); //由于j必须要凑满(甚至大于) 所以初值先赋一个小的
//因为鉴定费不能少只能多,那么只能初始化极小值,求的是刚好够
for(int i=1;i<=d.size();i++){
for(int j=0;j<=spz;j++){
if(j-d[i].p1>=0)
dp[i%2][j]=max(dp[(i-1)%2][j-d[i-1].p1]+d[i-1].p1,dp[(i-1)%2][j]+d[i-1].p2-m);
//dp[i][j]=max(dp[i-1][j-p1]+p1,dp[i-1][j]+p2-m);
// 又有了p1的鉴定费,相当于要凑的j少了p1
// 鉴了,并且加上它获得的价值
else //鉴定费太够了,防越界
dp[i%2][j]=dp[(i-1)%2][j]+d[i-1].p2-m;
}
}
int ans=0;
for(int j=m-bm;j<=spz;j++)
ans=max(ans,dp[d.size()%2][j]);
cout<<ans+bm<<endl;
return 0;
}
评论:
using namespace std; struct magic {
int p1;
int p2;
}; vector re; int dp[5001]; const int INF = 999999999; int main() {
int money = 0; int t1 = 0,t2=0;
int n, m;
cin >> n >> m;
string s;
getline(cin, s);
for (int i = 0; i < n; i++) {
getline(cin, s);
if (s.find(' ') == -1) {
money += stoi(s);
}
else {
int p1 = stoi(s.substr(0, s.find(' ')));
int p2 = stoi(s.substr(s.find(' ')+1));
if (p2 - p1 <= m) money += p1;
else {
re.push_back({ p1,p2 });
t2 += p2 - m;
t1 += p1;
}
}
}
if (money >= m) {
cout << money + t2;
return 0;
}
if (money + t1 <= m) {
cout << money + t1;
return 0;
}
fill(dp, dp + t1 + 1, INF);
dp[0] = 0;
for (int i = 0; i < re.size(); i++)
{
for (int j = t1; j>= re[i].p1; j--) {
dp[j] = min(dp[j], dp[j - re[i].p1] + re[i].p2 - re[i].p1 - m);
}
}
int best = INF;
for (int i = m - money; i <= t1; i++) best = min(best, dp[i]);
cout << money + t2 - best;
return 0;
}
请先登录,才能进行评论