acm寒假集训第六讲总结
1.最大子段和
思路:
遍历数组,每一步都有两种情况,继续累加或者开始一个新的子段,依靠做出选择后的结果哪个更大来判断,另外使用一个变量记录最大的子段和即可
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,i;
cin>>n;
int a[n];
for(i=0;i<n;i++)
{
cin>>a[i];
}
int sum=a[0],sum_all=a[0];
for(i=1;i<n;i++)
{
if(a[i]+sum>a[i])
{
sum+=a[i];
if(sum>sum_all)
{
sum_all=sum;
}
}
else
{
sum=a[i];
if(sum>sum_all)
{
sum_all=sum;
}
}
}
cout<<sum_all;
}
2.采药
思路:
使用0-1背包的模型,转移方程为f[j]=max(f[j],f[j-h[i].time]+h[i].value),即每种草药要么装入要么不装
代码:
#include <bits/stdc++.h>
using namespace std;
struct herb
{
int time,value;
};
int main()
{
int t,m;
cin>>t>>m;
int i,j;
vector<struct herb> h;
for(i=0;i<m;i++)
{
struct herb h1;
cin>>h1.time>>h1.value;
h.push_back(h1);
}
vector<int> f(t+5,0);
for(i=0;i<m;i++)
{
for(j=t;j>=h[i].time;j--)
{
f[j]=max(f[j],f[j-h[i].time]+h[i].value);
}
}
cout<<f[t];
return 0;
}
3.宝物筛选
思路:
使用多重背包的思路,为了保证不会TLE,使用二进制优化降低时间复杂度
代码:
#include <bits/stdc++.h>
using namespace std;
struct treasure
{
long long int weight, value, number;
};
int main()
{
long long int n, w;
cin >> n >> w;
vector<struct treasure> t;
for (long long int i = 0; i < n; i++)
{
struct treasure t1;
cin >> t1.value >> t1.weight >> t1.number;
t.push_back(t1);
}
vector<long long int> f(w + 1, 0);
for (long long int i = 0; i < n; i++)
{
long long int value = t[i].value, weight = t[i].weight, number = t[i].number;
for (long long int k = 1; k <= number; k *= 2)
{
number -= k;
for (long long int j = w; j >= weight * k; j--)
{
f[j] = max(f[j], f[j - weight * k] + value * k);
}
}
if (number > 0)
{
for (long long int j = w; j >= weight * number; j--)
{
f[j] = max(f[j], f[j - weight * number] + value * number);
}
}
}
cout << f[w];
return 0;
}
4.最长公共子序列
思路:
通过将最长公共子序列问题最长递增子序列问题降低时间复杂度,防止TLE
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> p1(n + 1), p2(n + 1);
for (int i = 1; i <= n; i++) cin >> p1[i];
for (int i = 1; i <= n; i++) cin >> p2[i];
vector<int> pos(n + 1, 0);
for (int i = 1; i <= n; i++)
{
pos[p2[i]] = i;
}
vector<int> seq;
for (int i = 1; i <= n; i++)
{
int val = pos[p1[i]];
if (val == 0) continue;
auto it = lower_bound(seq.begin(), seq.end(), val);
if (it == seq.end())
{
seq.push_back(val);
}
else
{
*it = val;
}
}
cout << seq.size();
return 0;
}
学习总结:
通过这次的学习,我学习了动态规划的相关知识,通过列出转移方程解决问题,主要学习了背包问题,包括0-1背包和多重背包,还了解到可以通过滚动数组避免MLE和使用二进制优化避免TLE的方法
浙公网安备 33010602011771号