筛法以及其他闲扯

筛法:

NOIP2018货币系统

首先证明答案就是这组数中不能被其他数凑出来的数的个数。这个我不会证,证明我也看不懂。但是可以意会

然后就是如何去掉能被其他数凑出来的数。题解里的dp我没看懂,但我觉得这个筛法挺好用的。。。

大体思想就是先把数组排一下序,然后对于每一个\(a_i\),如果它没被筛过,那么从\(a_i\)筛到\(a_{max}\),


for(int j=a[i]+1;j<=maxx;++j)
    if(vis[j-a[i]]==1)
        vis[j]=1;

...应该比较好理解...

Code


#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N = 1000001;
int T,n;
int a[N],f[N],vis[N];

inline void clear(int n) {for(int i=1;i<=n;++i) vis[i]=0;}

int main()
{
    scanf("%d",&T);
    vis[0]=1;
    while(T--)
    {
        int cnt=0,maxx=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {scanf("%d",&a[i]);maxx=max(maxx,a[i]);}
        sort(a+1,a+n+1);
        for(int i=1;i<=n;++i)
        {
            if(vis[a[i]]==1) continue;
            ++cnt;
            vis[a[i]]=1;
            for(int j=a[i]+1;j<=maxx;++j) if(vis[j-a[i]]==1) vis[j]=1;
        }
        printf("%d\n",cnt);
        clear(maxx);
    }
    return 0;
}

一道练筛法的题

这题挺好的,小凯的疑惑+筛法 +卡常

第一问就是小凯的疑惑(一开始没看懂题意

第二问就是筛法了。挂个代码就明白了qwq:

Code


#include<iostream>
#include<cstdio>
#include<map>

using namespace std;

const int N = 4.9e7;
int n,a,b,maxx,ans;
int m[N];

int main()
{
    m[0]=233;
    scanf("%d%d%d",&a,&b,&n); 
    maxx=a*b-a-b;
    for(int i=a;i<=maxx;++i)
        if(m[i-a]==233) m[i]=233;
    for(int i=b;i<=maxx;++i)
        if(m[i-b]==233) m[i]=233;

    for(int i=1;i<=n;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(x>maxx||m[x]==233)
            ans+=y;
    }
    printf("%d %d\n",maxx,ans);
    return 0;
}

其他闲扯:

做这两道题花了一晚上,自己还是太辣鸡了。。。

lrk的卡常太强辣!orzorz

再就是感觉做过的题还没有完全理解,

基础没有巩固好,学了太多较难算法,忘记了基础的怎么打。。。

以后做题一定不看题签,尽量少做裸题等。

今天考初赛,就先写到这叭~

祝wyh CSP rp++ !

上一篇:校内模拟赛 ——— 2019.10.31 7:40至11.10


下一篇:CodeForces 1467B - Hills And Valleys