Atcoder Beginning Contest 251

D(补)

题意:
给你一个数字w,让你给出300个以内的数字,范围在1e6之内,使得这些数字里面你可以最多选三个,都能够形成1~w里的所有数字;

思路:100进制;w成立,实际上w没什么用,让1e6成立就代表前面的都成立;
可以把数字分成三组,\(a_1a_2b_1b_2c_1c_2\),这种情况下可以表示1~999999,再加上1e6即可;
代码:

//构造100进制
#include <bits/stdc++.h>
using namespace std;
vector<int>ans;
int main(){
	int n;
	scanf("%d",&n);
	for (int i=1;i<=99;i++) ans.push_back(i);
	for (int i=1;i<=99;i++) ans.push_back(i*100);
	for (int i=1;i<=100;i++) ans.push_back(i*10000);
	printf("%d\n",ans.size());
	for (int i=0;i<ans.size();i++){
		printf("%d ",ans[i]);
	}
}

E(补)

题意:
你有n只动物,你可以喂给他们食物,喂了第\(i\)头时第\(i+1\)头也会被喂,当然第\(n\)头和第1头是关联的,喂不同的动物有不同的花费,问如何让花费最少?

思路:
dp,感觉应该是比较典型的一个dp;喂了一只之后,下一只可以不喂,也可以喂,分成两种情况:喂第一头和不喂第一头;

代码:

//补,dp
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
ll f[N][2];
//f[i][0]表示选了,f[i][1]表示没选
int n,a[N];

int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	//选择a[1]
	f[1][0]=1e18,f[1][1]=a[1];
	for (int i=2;i<=n;i++){
		f[i][0]=f[i-1][1];
		f[i][1]=min(f[i-1][0],f[i-1][1])+a[i];
	}
	ll ans=min(f[n][0],f[n][1]);
	//不选a[1]
	f[1][0]=0,f[1][1]=1e18;
	for (int i=2;i<=n;i++){
		f[i][0]=f[i-1][1];
		f[i][1]=min(f[i-1][0],f[i-1][1])+a[i];
	}
	ans=min(ans,f[n][1]);//第n个肯定选
	printf("%lld\n",ans);
}
posted @ 2022-05-17 16:05  无疾  阅读(32)  评论(0)    收藏  举报