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);
}

浙公网安备 33010602011771号