应该说是很难的一个题了
首先,要想到这种求最大值的应该转化成01背包,si作为容量,fi作为价值。
然后,要解决容量为负值的问题,那就再加一个数组用来存储加进去了多少个原本是负值的si
最后,在求最终答案的时候,记得把为了成为正数多加的减掉
class Solution { public: /** * * @param number int整型 参加校招的同学人数 * @param si int整型一维数组 这个同学的聪明值 * @param siLen int si数组长度 * @param fi int整型一维数组 这个同学的勤奋值 * @param fiLen int fi数组长度 * @return int整型 */ int smartSum(int number, int* si, int siLen, int* fi, int fiLen) { // write code here int sum = 0; int dp[100000],cnt[100000]; int ans; for (int i = 0; i < number; i ++) { if(si[i]<0&&fi[i]<0) { si[i] = 0;fi[i]= 0; continue; } si[i]+=1000; sum+=si[i]; } for(int i=sum+100;i>=0;--i) dp[i]=-0x3f3f3f3f,cnt[i]=0; dp[0]=0; for(int i=0;i<number;++i) { for(int j=sum;j>=si[i];--j) { if(dp[j-si[i]]+fi[i]-(cnt[j-si[i]]+1)*1000>dp[j]-(cnt[j])*1000) { dp[j]=dp[j-si[i]]+fi[i]; cnt[j]=cnt[j-si[i]]+1; // cout<<cnt[j]<<endl; } } } ans=0; for(int i=sum;i>=0;--i) if(i-(cnt[i])*1000>0&&dp[i]>0) ans=max(ans,dp[i]+i-(cnt[i])*1000); return ans; } };
时间复杂度和空间复杂度就是01背包的
貌似解法也就这么一个。。