洛谷100题计划(30/100)

洛谷100题计划(30/100)

P1628 合并序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

把符合条件的字符串都放进multiset里(可以包含重复的元素,且自动排序),然后输出即可

#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<string> s(N);
    for (auto &i : s)
        cin >> i;

    string T;
    cin >> T;

    multiset<string> ans;
    for(auto &i : s){        
        if(i.size() < T.size()) continue;
        if(i.substr(0,T.size()) == T)
            ans.insert(i);
    }

    for(auto i : ans)
        cout << i << '\n';

    return 0;
}

P1403 [AHOI2005] 约数研究 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

先给出公式\(ans += \lfloor\frac{N}{i}\rfloor\),这里的\(\lfloor\frac{N}{i}\rfloor\)意思是\(1\sim N\)中有多少个数的约数包含\(i\),以题干中举例:

1 2 3 4 5 6
1 1 1 1 1 1
2 2 2
3 3
4
5
6
#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;

    i64 ans = 0;
    for(int i = 1;i <= N;i ++){
        ans += N / i;
    }

    cout << ans << '\n';

    return 0;
}

P1644 跳马问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

看数据范围比较小,直接dfs暴搜了,dp应该也能做,不过感觉没直接dfs好写(

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {

	int n,m;
	cin >> n >> m;

	int u[] = {-2,-1,1,2},v[] = {1,2,2,1};
	
	i64 ans = 0;
	auto dfs = [&](auto self, int x,int y){
		if(x > n || y > m || x < 0 || y < 0)
			return ;

		if(x == n && y == m){
			ans ++;
			return ;
		}

		for(int i = 0;i < 4;i ++){
			self(self,x + u[i], y + v[i]);
		}
	};

	dfs(dfs,0,0);
	cout << ans << '\n';

	return 0;
}

P1122 最大子树和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)(树形dp)

按照题目的要求可以可以建成一棵树,而要使得修剪一些花朵使得剩下的花朵的美丽值最大,我们则可以以每个结点为根去统计它的子节点中美丽值大于\(0\)的花朵,最后遍历一遍选取以\(i\)结点为根的剩余美丽值最大的即可

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

int main() {

	int n;
	cin >> n;

	vector<int> a(n + 1);
	for(int i = 1;i <= n;i ++)
		cin >> a[i];

	vector<vector<int>> g(n + 1,vector<int>());

	for(int i = 1;i < n;i ++){
		int x,y;
		cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}

	vector<i64> dp(n + 1);
	auto dfs = [&](auto self, int u,int fa)->void{
		dp[u] += a[u];
		for(auto i : g[u]){
			if(i == fa) continue;
			self(self,i,u);
			if(dp[i] > 0) dp[u] += dp[i];
		}
	};

	dfs(dfs,1,0);
	i64 ans = INT_MIN;
	for(int i = 1;i <= n;i ++)
		ans = max(ans, dp[i]);

	cout << ans << '\n';

	return 0;
}

P1510 精卫填海 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

此题就是一个背包题,但是有个很坑的点,就是不一定刚好满足体积\(v\)的就是体力最小的,大于\(v\)的也可以填满,所以得开大一点,这里是直接开到了\(2v\)

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {

	int v,n,c;
	cin >> v >> n >> c;
	vector<i64> k(n),m(n);
	for(int i = 0;i < n;i ++)
		cin >> k[i] >> m[i];

	vector<i64> dp(2 * v + 1,INT_MAX);
	dp[0] = 0;
	i64 resv = INT_MAX;
	for(int i = 0;i < n;i ++){
		for(int j = 2 * v;j >= k[i];j --){
			dp[j] = min(dp[j], dp[j - k[i]] + m[i]);
		}		
	}

	for(int i = v;i <= 2 * v;i ++)
		resv = min(resv, dp[i]);

	if(resv <= c) cout << c - resv << '\n';
	else cout << "Impossible\n";

	return 0;
}
posted @ 2023-09-24 00:04  Ke_scholar  阅读(12)  评论(0编辑  收藏  举报