2018
T1 铺设道路
差分水题,推一下结论就好了。
#include<cstdio> #include<algorithm> using namespace std; int a[100005],d[100005],ansz,ansf; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),d[i]=a[i]-a[i-1]; for(int i=1;i<=n;i++) { if(d[i]<0) ansf-=d[i]; else ansz+=d[i]; } printf("%d\n",max(ansz,ansf)); return 0; }
T2 货币系统
一开始以为是数学题,后来发现可以dp,很有意思的完全背包简单变形。
f数组下标存储每一个数,true表示已经出现,false表示不能被表示。
初始化f[0]为true。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,a[205],f[25005],T; int main() { scanf("%d",&T); while(T--) { int ans=0,maxn=0; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),maxn=max(maxn,a[i]); sort(a+1,a+1+n); memset(f,0,sizeof(f)); f[0]=true;//f的下标代表的是这个数是否出现过 for(int i=1;i<=n;i++) { if(f[a[i]])continue;//如果出现过 continue ans++;//默认没出过 for(int j=a[i];j<=maxn;j++) f[j]=max(f[j-a[i]],f[j]);//如果j-a[i]出现过,可以保证的是j也能出现,这就是一个true的赋值转移 } printf("%d\n",ans); } return 0; }