【P2340 [USACO03FALL]Cow Exhibition G】題解
阿新 • • 發佈:2021-11-18
題目連結
一道很好的01揹包變形題。
首先看一眼題很明顯可以發現是揹包。
此題我當時的第一反應是二維費用揹包,然而會TLE+MLE,於是開啟題解思考01揹包做法。
設 \(dp_i\) 代表智商和為 \(i\) 時情商的最大值。
\[dp_i=\max_{j=1}^n(dp_{i-s_j}+f_j) \]經典的01揹包轉移。
最後答案為 \(\max (dp_i+i) (dp_i\geqslant 0,\,i\geqslant 0)\) 。
然而我們發現有些奶牛很蠢,智商為負數,這時候與01揹包倒著來不同,要變成正著來。
同時由於智商和可能為負,所以要預設加400000。
Code
// Problem: P2340 [USACO03FALL]Cow Exhibition G // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P2340 // Memory Limit: 125 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; #define int long long inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+ (x<<3)+(ch^48);ch=getchar();}return x*f;} //#define M //#define mo //#define N int n, m, i, j, k; int dp[800010]; int s, f, ans; signed main() { // freopen("tiaoshi.in", "r", stdin); // freopen("tiaoshi.out", "w", stdout); memset(dp, 0xAA, sizeof(dp)); dp[400000]=0; n=read(); for(i=1; i<=n; ++i) { s=read(); f=read(); if(s>=0) { for(j=800000; j>=s; --j) dp[j]=max(dp[j], dp[j-s]+f); } else { for(j=0; j-s<=800000; ++j) dp[j]=max(dp[j], dp[j-s]+f); } } for(i=400000; i<=800000; ++i) { if(dp[i]>=0) ans=max(ans, i-400000+dp[i]); // printf("dp(%lld)=%lld\n", i, dp[i]); } printf("%lld", ans); return 0; }