1.202212-2原题网址
这题我觉得好难啊,满分答案学习一下,膜拜大佬!!!!
#include<iostream>
using namespace std;
struct
{
int form = 0;//先导课
int day = 0;//消耗
int start = 1;//最早
int last_start = 0;//最晚
}course[105];
int main()
{
int max = -1;
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> course[i].form;
}
for (int i = 0; i < m; i++)
{
cin >> course[i].day;
}
for (int i = 0; i < m; i++)
{
if (course[i].form != 0)
{
course[i].start = course[course[i].form - 1].start + course[course[i].form - 1].day;//该门课的最早开始时间为先导课最早结束时间
}
cout << course[i].start << " ";//输出最早开始时间
if ((course[i].day + course[i].start) > max)//判断是否能上完课
max = course[i].day + course[i].start - 1;
}
if (max <= n)//能上就输出
{
cout << endl;
for (int i = m - 1; i >= 0; i--)
{
if (course[i].last_start == 0)
course[i].last_start = n - course[i].day + 1;
if (course[i].form != 0)
{
int temp = course[i].last_start - course[course[i].form - 1].day;
if (course[course[i].form - 1].last_start == 0)
{
course[course[i].form - 1].last_start = temp;
}
else
{
course[course[i].form - 1].last_start = min(temp, course[course[i].form - 1].last_start);
}
}
}
for (int i = 0; i < m; i++)
{
cout << course[i].last_start << " ";
}
}
return 0;
}
2.202209-2原题网址
DP思路(100分大佬思路):
01背包问题,书的价格既是价值又是体积。
最多有30本书,每本书最多10000,我们开一个300010的背包就可以了。
注意用一个变量sum表示当前所有书的价格,这就是我们当前的体积
#include<iostream>
using namespace std;
const int N = 300010;
int n, m, v, sum;
int f[N];
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> v;
sum += v;
for (int j = sum; j >= v; j--) {
f[j] = max(f[j], f[j - v] + v);
}
}
for (int i = m;; i++) {
if (f[i] >= m) {
cout << f[i];
break;
}
}
return 0;
}
DFS(70分能看懂思路)
#include <bits/stdc++.h>
using namespace std;
const int N = 35;
int n, m;
int v[N];
int minn = 1000010;
void dfs(int u, int now) {
if (minn == m)return;
for (int i = u; i < n; i++) {
if (now + v[i] >= m && now + v[i] < minn) {//情况2
minn = now + v[i];//更新最小花费
}
else if (now + v[i] < m) {//情况1
dfs(i + 1, now + v[i]);//判断下一本书
}
}
return;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> v[i];
dfs(0, 0);
cout << minn;
return 0;
}
3.202109-1原题网址
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int b[1000] = { 0 }, a[1000] = { 0 };
for (int i = 0; i < n; i++)
cin >> b[i];
a[0] = b[0];
int sum_max = a[0], sum_min = a[0];
for (int i = 1; i < n; i++)
{
a[i] = b[i];
sum_max += b[i];
if (b[i] == b[i - 1])
a[i] = 0;
sum_min += a[i];
}
cout << sum_max << endl << sum_min << endl;
return 0;
}
- 202109-2原题网址
菜鸡50分代码(呜呜呜)
#include<iostream>
#include<algorithm>
using namespace std;
int num[500000] = { 0 }, num1[500000] = { 0 };
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> num[i];
num1[i] = num[i];
}
sort(num1, num1 + n);
int p = 0;
int max = 0;
for (int i = 0; i < n; i++)
{
while (p <= num1[n - 1] + 1)
{
p++;
int duan = 0;
for (int j = 0; j < n - 1; j++)
{
if (num[j] >= p && num[j + 1] < p)
duan++;
}
if (num[n - 1] >= p && num[n - 2] < p)
duan++;
if (duan > max)
max = duan;
}
}
cout << max << endl;
return 0;
}
满分答案
#include <iostream>
using namespace std;
const int N = 1e6;
int dif[N], a[N];
int n;
void add(int l, int r) { dif[l]++, dif[r + 1]--; }
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) {
if (a[i - 1] < a[i]) {
add(a[i - 1] + 1, a[i]);
}
}
int maxn = 0, pre = 0;
for (int p = 1; p < 1e4; p++) {
pre += dif[p];
maxn = max(maxn, pre);
}
cout << maxn;
return 0;
}
理解
此方法用到前缀和以及差分的思想
原博客引用
总结
在函数内部定义过大的函数时会爆栈,我第一次写的时候(暴力法),每次改变p值时都在循环内定义一个新数组来存储改变后的数组。然后程序也没有报错,但是运行时就是自己中断了,问了大佬才知道原来在还是内部定义太大的数组时会爆栈,所以以后尽量把函数定义在main函数前。
加深理解前缀和,了解了差分这种算法。