AtCoder ABC169

可惜沒打成這場,要不然應該可以AK的/kk/fad

E

有一個數列{xi}\{x_i\},滿足lixiril_i\leq x_i\leq r_i,現在對於給定的li,ril_i,r_i,求這個數列的中位數可能有多少種不同的情況

這道題還是比較好想的,一個點能否成爲中位數,就是他左邊和右邊的xix_i的數量相同

我們對於左端點和右端點進行排序,就可以找到他的範圍了

注意對於奇數和偶數進行分類討論

#include <bits/stdc++.h>
using namespace std;

# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)

typedef long long ll;

const int N=2e5+5;

template<typename T> void read(T &x){
   x=0;int f=1;
   char c=getchar();
   for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
   for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
    x*=f;
}

int n;
int l[N],r[N];
int p,q;

int main()
{
    read(n);
    Rep(i,1,n)read(l[i]),read(r[i]);
    sort(l+1,l+n+1);
    sort(r+1,r+n+1);
    if(n%2==0){
        p=l[n>>1]+l[(n>>1)+1],q=r[n>>1]+r[(n>>1)+1];
        printf("%d\n",q-p+1);
    }
    else{
        p=l[n+1>>1],q=r[n+1>>1];
        printf("%d\n",q-p+1);
    }
    return 0;
}

F

現在有一個長度爲nn的序列{ai}\{a_i\}
設全集U={1,2,3,,n}U=\{1,2,3,\cdots ,n\}TTUU的一個非空子集,現在定義f(T)f(T)表示不同的TT的非空子集PP的個數,是的aPi=S\sum a_{P_i}=S
現在對於每一個TT,求f(T)\sum f(T)

n,S,ai3000n,S,a_i\leq 3000

首先考慮如果T=UT=U的時候怎麼求

非常的簡單,就是一個非常樸素的揹包
我們用f[i][j]f[i][j]表示前ii個數,和爲jj的方案數,那麼有f[i][j]=f[i1][j]+f[i1][jx[i]]f[i][j]=f[i-1][j]+f[i-1][j-x[i]]

顯然我們需要更改一下狀態:f[i][j]f[i][j]表示由前ii個數組成的所有集合中,選出和爲jj的方案數總和
那麼怎麼求出每一個集合的方法呢?
我們把最開始的轉移看成兩部分

  • f[i1][j]f[i-1][j]轉移過來,此時我們求和時不選xix_i,那麼也就是說,不管我們的集合裏面選不選ii,這個方案一直都在,所以這時候的轉移量應該是f[i1][j]×2f[i-1][j]\times 2
  • f[i1][jx[i]]f[i-1][j-x[i]],這個時候我們必須選擇xix_i,所以他應該算到答案的集合裏面必須有ii,所以方案數不變

那麼我們的轉移就變成了f[i][j]=f[i1][j]×2+f[i1][jx[i]]f[i][j]=f[i-1][j]\times2+f[i-1][j-x[i]]

初值f[0][0]=1f[0][0]=1

答案f[n][S]f[n][S]

然後就輕鬆通過了qwq

#include <bits/stdc++.h>
using namespace std;

# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)

typedef long long ll;

const int N=3005;
const int mod=998244353;

template<typename T> void read(T &x){
   x=0;int f=1;
   char c=getchar();
   for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
   for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
    x*=f;
}

int n,m;
int a[N];
int f[N][N];
int mi[N];

int main()
{
    read(n),read(m);
    Rep(i,1,n)read(a[i]);
    f[0][0]=1;
    Rep(i,1,n){
        Rep(j,0,m){
            f[i][j]=f[i-1][j]*2%mod;
            if(j>=a[i])f[i][j]+=f[i-1][j-a[i]],f[i][j]%=mod;
        }
    }
    printf("%d\n",f[n][m]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章