xiao方法
#include<stdio.h> #include<vector> #include<iostream> using namespace std; int main() { int data[10] = {4,7,6}; int flag1 = 0xffffff, flag2 = 0xffffff; int sum = 0; int res = 0; for(int i = 0; i < 3; i++) { sum += data[i]; if(data[i]%3==1 && data[i]<flag1) { flag1 = data[i]; } else if(data[i]%3==2 && data[i]<flag2) { flag2 = data[i]; } if(sum%3==0 && sum>res) { res = sum; } else if(sum%3==1 && flag1<0xffffff) { res = sum-flag1>res?sum-flag1:res; } else if(sum%3==2 && flag2<0xffffff) { res = sum-flag2>res?sum-flag2:res; } } cout<<res<<endl; return 0; } int divide_3(vector<int> input,int length){ vector<int> dp(length); for(int i = 0;i < length;i++){ } }
正负都能解决
#include <cstdio> #include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { int input[] = {-1,2,6,7}; vector<int> data(input,input+4); int n = data.size(); vector<vector<int> > dp(n+1,vector<int>(3,-1)); dp[0][0] = 0; for(int i = 1;i <= n;i++){ for(int j = 0;j < 3;j++){ dp[i][j] = max(dp[i][j],dp[i-1][j]); if(dp[i-1][j] < 0) continue; int temp = (data[i-1] + j) % 3; dp[i][temp] = max(dp[i-1][temp], dp[i-1][j] + data[i-1]); } } cout << dp[n][0] << endl; return 0; }
第一题用DFS是肯定可以做的,但我当时想的是先排个序,然后greedy地取集合里的所有数,看看除3余几
1) 如果余0直接return
2) 如果余1,考虑是丢掉一个最小的除3余1的数,还是丢掉两个最小的除3余2的数.留学论坛-一亩-三分地
3) 如果余2也是类似的
后来跟面试官讨论发现其实不用排序。。打个擂台就能找了(但其实我是想着排序了代码好写一点orz)
优化后时间复杂度是O(n),本来还担心这个方法会不会有点野鸡,但是讲道理效率确实比DFS好得多。。。
follow up: 加入负数的话也是类似的,一开始greedy地取所有正数,然后再考虑是丢掉最小的正数还是加入最大的负数,复杂度一样