NOIP提高组历年真题题解

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

猜你喜欢

转载自www.cnblogs.com/valentino/p/11743402.html