題意:每件事有三個屬性,人品值a,門檻b,獲益c,如果a>0,小於這個門檻b的可以做這件事,收益c為負,反之,如果a<0,大於這個門檻值b可以做,收益c為正.
思路:由於人品值可為正負,統一加10000都處理為正,定義dp[n] 為,人品值為n時的最大效益,這裡需要標記一下人如果加入這件事後,品值為n的是否出現過,沒有就直接更新,有就取最優解的.
#include <fstream>#include <iostream>#include <string>#include <cstring>#include <complex>#include <math.h>#include <set>#include <vector>#include <map>#include <queue>#include <stdio.h>#include <stack>#include <algorithm>#include <list>#include <ctime>#include <memory.h>#include <ctime>#include <assert.h>#define rep(i,a,n) for (int i=a;i<n;i++)#define per(i,a,n) for (int i=n-1;i>=a;i--)#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define fi first#define se second#define eps 1e-8#define M_PI 3.141592653589793typedef long long ll;const ll mod=1000000007;const int inf=0x7fffffff;ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}int dp[21000],v[21000];int a[1010],b[1010],c[1010];using namespace std;int main(){ ios::sync_with_stdio(false); int T;cin>>T; while(T--){ int n;cin>>n; for(int i=0;i<n;i++) cin>>a[i]>>b[i]>>c[i]; memset(dp,0,sizeof(dp)); memset(v,0,sizeof(v)); v[10000]=1; for(int i=0;i<n;i++){ if(a[i]>0){ for(int j=10000+b[i];j>=0;j--){ if(v[j]){ if(!v[j+a[i]]){ v[j+a[i]]=1; dp[j+a[i]]=dp[j]+c[i]; } else{ dp[j+a[i]]=max(dp[j+a[i]],dp[j]+c[i]); } } } } else{ for(int j=10000+b[i];j<=20010;j++){ if(v[j]){ if(!v[j+a[i]]){ v[j+a[i]]=1; dp[j+a[i]]=dp[j]+c[i]; } else{ dp[j+a[i]]=max(dp[j+a[i]],dp[j]+c[i]); } } } } } int res=0; for(int i=0;i<20100;i++) res=max(res,dp[i]); cout<<res<<endl; }}
寒假培訓已經快過一小半,路漫漫其修遠兮,吾將上下而求索!