POJ-2184 Cow Exhibition 【動態規劃DP+01揹包變換】
阿新 • • 發佈:2018-11-19
題目:共有N頭牛,接下來N行是每頭牛的智商和情商,從這些牛中任意選取若干頭牛,使得牛的智商和+情商和最大,同時智商和(TS),情商和(TF)都不小於0。
題解:以智商作為容量,求前i頭牛在智商為j的情況下的最大情商 。因為有負數,所以容量擴大100000,修改dp陣列的起始位置為mid, 1—mid 為處理負數的區間 mid—N為處理正數的區間。初始化dp時,因為有負數,所以初始化為一個非常小的負數,起始點dp[mid]=0。dp[i][j]優化掉第i維,然後套01揹包。正負數時揹包不同。情商和TF通過dp陣列可以得到,智商和TS通過dp陣列的下標和起始點對比得到(TS[i]=i-mid)。
AC程式碼:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define inf 99999999 typedef long long ll; const int mod=1e9+7; const int maxn=1e5+7; const int N=200005; const int mid=100000; int n; int w[105],v[105],dp[N]; int main() { io; cin>>n; for(int i=1; i<=n; i++) cin>>w[i]>>v[i]; for(int i=0; i<=N; i++)//初始化dp,因為有負數,所以初始化為一個非常小的負數 dp[i]=-inf; dp[mid]=0;//起始點初始化為0 for(int i=1; i<=n; i++) { if(w[i]>0) { for(int j=N-1; j>=w[i]; j--)//正數時候的揹包 dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } else { for(int j=0; j<N+w[i]; j++)//負數時候的揹包 dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } int ans=0; for(int i=mid; i<=N; i++)//從智商和為0開始 { if(dp[i]>=0)//情商和大於0 ans=max(ans,dp[i]+i-mid);//dp陣列存的是TF,通過i-mid計算TS } cout<<ans<<endl; return 0; }