D1T1:
这题是十分简单的,我们很容易就能得到一种证明:每次答案只要加上这一段的峰值。因为若是小于这一峰值,便不必重复累加。
#include<bits/stdc++.h>
using namespace std;
int n,a,last,ans;
int main(){
cin>>n;
while(n--){
cin>>a;
if(a>last)
ans+=a-last;
last=a;
}
cout<<ans;
}
D1T2:
这一题我们可以通过一种类似于线性筛的做法得出可达到的面值,首先将原货币从小到大进行一次排序,然后从最小的面值开始,依次判断是否已经被覆盖,若未被覆盖,则答案加一,并且加入筛中:将从一到最大值的每一个可以达到的数值再加上此新数。
#include<bits/stdc++.h>
using namespace std;
int n,s[105],sj,m,T;
bool ver[25005];
inline int read(){
int f=1,k=0;
char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-')
f=-1;
for(;isdigit(c);c=getchar())
k=k*10+c-'0';
return k*f;
}
inline void dfs(int num){
ver[num]=true;
for(int i=1;i+num<=sj;i++){
if(!ver[i])
continue;
ver[i+num]=true;
}
return ;
}
int main(){
T=read();
while(T--){
m=0;
n=read();
for(int i=1;i<=sj;i++)
ver[i]=false;
for(int i=1;i<=n;i++)
s[i]=read(),sj=max(s[i],sj);
sort(s+1,s+1+n);
if(s[1]==1){
cout<<1<<endl;
continue;
}
for(int i=1;i<=n;i++){
if(!ver[s[i]])
m++,dfs(s[i]);
}
cout<<m<<endl;
}
return 0;
}