股票买卖 III
//1次交易的话,第i天的最大收益需要找到前i-1天的min
#include <iostream>
using namespace std;
const int N = 1e5+10;
int n, p[N], g[N], f[N];
int main()
{
cin>>n;
for(int i = 1; i <= n; i ++) cin>>p[i];
//g[i]是1-i中交易一次的max值
for(int i = 2, minv = p[1]; i <= n; i ++)
{
g[i] = max(g[i-1], p[i] - minv);
minv = min(minv, p[i]);
}
//f[i]是i-n中交易一次的max值
for(int i = n - 1, maxv = p[n]; i >= 1; i --)
{
f[i] = max(f[i+1], maxv - p[i]);
maxv = max(maxv, p[i]);
}
//遍历分界点
int res = 0;
for(int i = 2; i <= n; i ++) res = max(res, g[i] + f[i+1]);
cout<<res<<endl;
return 0;
}
1487.取硬币
完全背包问题是n*n复杂度:
01从大到小,完全从小到大
//前n1个是01背包,后n2个是完全背包
#include <iostream>
using namespace std;
const int N = 100010, MOD = 1e9+7;
int n1, n2, m;
int f[N];
int main()
{
cin>>n1>>n2>>m;
f[0] = 1;
for(int i = 1; i <= n1; i ++)
{
int p;
cin>>p;
for(int j = p; j <= m; j ++) f[j] = (f[j] + f[j-p]) % MOD;
}
for(int i = 1; i <= n2; i ++)
{
int p;
cin>>p;
for(int j = m; j>= p; j --) f[j] = (f[j] + f[j-p]) % MOD;
}
cout<<f[m]<<endl;
return 0;
}
1488. 最短距离
普通做法要n*n复杂度,采用超级源点,向每一个商店连有向边,求s到所有点的单源最短路径,复杂度o(m)
1489. 田忌赛马
//不能赢的马只有平和输两种情况,输的话可以当作炮灰死得其所,让另一局赢
//贪心问题,一部分的解通过分析可以直接去掉
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n;
int a[N], b[N];
int judge(int x, int y)
{
if(a[x] > b[y]) return 1;
if(a[x] < b[y]) return -1;
return 0;
}
int main()
{
while(cin >> n, n)
{
for(int i = 0; i < n; i ++) cin>>a[i];
for(int i = 0; i < n; i ++) cin>>b[i];
//从大到小排序,只用分析最快和最慢的,因为去掉这两个马剩下的马里面还有最快和最慢的
sort(a, a+n, greater<int>());
sort(b, b+n, greater<int>());
int f1 = 0, f2 = 0, s1 = n - 1, s2 = n - 1;
int res = 0;
while(f1 <= s1)//田的马小于国王的,分情况
{
if(judge(s1, s2) > 0) res ++, s1 --, s2 --;
else if(judge(s1, s2) < 0) res += judge(s1, f2),s1 --, f2 ++;//如果要输,就打国王最快的
else
{
if(judge(f1, f2) > 0) res ++, f1++, f2++;
else res += judge(s1, f2), s1--, f2 ++;//剩下两种情况
}
}
cout<< res * 200<<endl;
}
return 0;
}
77. 翻转单词顺序
/*
for(int i = 0, j = s.size() - 1; i < j; i++,j--) swap(i,j);反转整个字符串
*/
//要求o(n)时间o(1)空间,类似矩阵翻转的题,拆解,先翻转整个句子,再翻转单个单词
class Solution {
public:
string reverseWords(string s) {
reverse(s.begin(), s.end());
//经典结构:新变量j找空格
for(int i = 0; i < s.size(); i ++)
{
int j = i;
while(j < s.size() && s[j] != ' ') j ++;
reverse(s.begin() + i, s.begin() + j);
i = j;
}
return s;
}
};