hdu 4945 DP

来源:互联网 发布:mysql替换字符串 编辑:程序博客网 时间:2024/06/14 09:51

//代码1:#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <sstream>#include <map>#include <set>#include <queue>#include <stack>#include <fstream>#include <numeric>#include <iomanip>#include <bitset>#include <list>#include <stdexcept>#include <functional>#include <utility>#include <ctime>#include <cassert>#include <complex>using namespace std;#define rep(i,a,n) for (int i=a;i<(int)n;i++)#define per(i,a,n) for (int i=n-1;i>=a;i--)#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define fi first#define se second#define SZ(x) ((int)(x).size())#define ACCU accumulate#define TWO(x) (1<<(x))#define TWOL(x) (1ll<<(x))#define clr(a) memset(a,0,sizeof(a))#define POSIN(x,y) (0<=(x)&&(x)<n&&0<=(y)&&(y)<m)#define PRINTC(x) cout<<"Case #"<<++__<<": "<<x<<endl #define POP(x) (__builtin_popcount(x))#define POPL(x) (__builtin_popcountll(x))typedef vector<int> VI;typedef vector<string> VS;typedef vector<double> VD;typedef long long ll;typedef long double LD;typedef pair<int,int> PII;typedef pair<ll,ll> PLL;typedef vector<ll> VL;typedef vector<PII> VPII;typedef complex<double> CD;const int inf=0x20202020;const ll mod=998244353;const double eps=1e-9;const double pi=3.1415926535897932384626;const int DX[]={1,0,-1,0},DY[]={0,1,0,-1};ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}ll powmod(ll a,ll b,ll mod) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}// headint cnt[3010];ll f[101000],g[101000];int pn,n,__;int dp[13][3010];inline int getint() {    int ret=0;bool ok=0;    for(;;) {        int c=getchar();        if(c>='0'&&c<='9')ret=(ret<<3)+ret+ret+c-'0',ok=1;        else if(ok)return ret;    }}int binom(int x,int y) {    if (x<y||y<0) return 0;    else return f[x]*g[y]%mod*g[x-y]%mod;}inline void upd(int &a,int b) { a+=b; if (a>=mod) a-=mod;}int main() {     f[0]=1; rep(i,1,100001) f[i]=f[i-1]*i%mod;g[100000]=powmod(f[100000],mod-2);    per(i,0,100000) g[i]=g[i+1]*(i+1)%mod;    while (1) {        n=getint();        if (n==0) break;        rep(i,0,12) cnt[TWO(i)]=0;        rep(i,0,n) cnt[getint()]++;        pn=0;        rep(i,0,12) pn+=cnt[TWO(i)];        rep(i,0,11) rep(j,0,TWO(10-i)) dp[i][j]=0; dp[11][0]=0;        int ct=cnt[1];        ll cof=f[ct];        rep(j,0,TWO(11)) {            if (j>ct) break;            upd(dp[0][j>>1],g[ct-j]%mod*g[j]%mod);        }        rep(i,0,11) {            ct=cnt[TWO(i+1)];            cof=cof*f[ct]%mod;            rep(j,0,TWO(10-i)) if (dp[i][j]) {                rep(k,0,TWO(10-i)) {                    if (k>ct||j+k>TWO(10-i)) break;                    upd(dp[i+1][(j+k)>>1],1ll*dp[i][j]*g[k]%mod*g[ct-k]%mod);                }            }        }        int ans=(powmod(2,pn)-dp[11][0]*cof)%mod*powmod(2,n-pn)%mod;        if (ans<0) ans+=mod;        printf("Case #%d: %d\n",++__,ans);    }}



//代码2:#include <iostream>#include <string>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <map>#include <set>#include <cmath>#include <sstream>#include <algorithm>#include <numeric>#define mp(x,y) make_pair(x,y)#define pb(x) push_back(x)#define sqr(x) ((x)*(x))using namespace std;const int INF = 0x3f3f3f3f;typedef long long ll;template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}const int mod = 998244353;ll fac[100005],rf[1000005],CC[100005],SC[100005];ll mpow(ll p,ll q){    ll res=1;    while(q){        if(q&1)            res=res*p%mod;        q>>=1;        p=p*p%mod;    }    return res;}ll C(int n,int m){return fac[n]*rf[m]%mod*rf[n-m]%mod;}ll dp[15][2050];int num[15],id[2050];int main(){    //freopen("1001.in","r",stdin);    fac[0]=rf[0]=1;    for(int i=1;i<=100000;++i){        fac[i]=fac[i-1]*i%mod;        rf[i]=mpow(fac[i],mod-2);    }    int N,cas=0;    for(int i=0;i<2050;++i)id[i]=12;    for(int i=0;i<12;++i)id[1<<i]=i;    while(~scanf("%d",&N),N){        memset(num,0,sizeof(num));        for(int i=0,a;i<N;++i){            scanf("%d",&a);            ++num[id[a]];        }        memset(dp,0,sizeof(dp));        ll ans=0;        /*1要预处理好_begin*/        for(int i=0;i<2048&&i<=num[0];++i)            dp[0][i]=C(num[0],i);        for(int i=2048;i<=num[0];++i)            {ans+=C(num[0],i);             ans %= mod;            }        /*1要预处理好_end*/        for(int i=1;i<12;++i){            int mm=2048>>i;            ans=ans*mpow(2,num[i])%mod;            ll s=0;            for(int n=0,t=mm+mm;n<=num[i];++n){                ll k=C(num[i],n);                for(int j=0;j+n<mm;++j)                    dp[i][j+n]=(dp[i][j+n]+k*(dp[i-1][j+j]+dp[i-1][j+j+1])%mod)%mod;                if(k)ans=(ans+k*s)%mod;                if(t){----t;s=(s+dp[i-1][t]+dp[i-1][t+1])%mod;}            }        }        printf("Case #%d: %I64d\n",++cas,ans*mpow(2,num[12])%mod);    }    return 0;}

//代码3#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cstdlib>#include <cmath>#include <queue>#include <vector>#include <map>#define pb push_back#define mp make_pair#define eps 1e-9#define zero(x) (fabs(x)<eps)#define pi acos(-1.0)#define f1 first#define f2 second#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define initial 1,n,1const int inf=0x3f3f3f3f;const long long INF=1LL<<50;using namespace std;typedef long long LL;typedef pair <int, int> PII;template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}const LL mod=998244353;#define N 2049#define T 100005int vis[N],n;int tr[15],num[15];LL fac[T],facc[T];int f[13][N];LL extend_gcd(LL a,LL b,LL &x,LL &y){    if(a==0&&b==0) return -1;    if(b==0){x=1;y=0;return a;}    LL d=extend_gcd(b,a%b,y,x);    y-=a/b*x;    return d;}LL quick(LL m,LL n,LL k){    LL b = 1;    while (n > 0)    {          if (n & 1)             b = (b*m)%k;          n = n >> 1 ;          m = (m*m)%k;    }    return b;}inline int getint() {    int ret=0;bool ok=0;    for(;;) {        int c=getchar();        if(c>='0'&&c<='9')ret=(ret<<3)+ret+ret+c-'0',ok=1;        else if(ok)return ret;    }}void doit(){   memset(f,0,sizeof(f));    int tmp=0;    int ans=0;    memset(num,0,sizeof(num));    for (int i=1,x;i<=n;i++)        {   x=getint();            if (vis[x]==-1) tmp++;else num[vis[x]]++;        }    f[12][0]=1;    for (int i=11,x,need;i>=0;i--)        {   x=tr[i];            LL tmp;            for (int k=2048,need=0,ss=0;;k-=x,need++)                {   if (num[i]<need) break;                    if (k>=0) ss=(ss+f[i+1][k])%mod;                    if (need) {tmp=fac[num[i]]*facc[need]%mod*facc[num[i]-need]%mod;                               ans=int((tmp*ss+ans)%mod);                              }                }            if (i==0) break; //少这句时间差4倍            for (int j=0;j<2048;j+=x)   if (f[i+1][j])            for (int k=j,need=0;k<=2048;k+=x,need++)                {   if (num[i]<need) break;                    tmp=fac[num[i]]*facc[need]%mod*facc[num[i]-need]%mod;                    f[i][k]=int((tmp*f[i+1][j]+f[i][k])%mod);                }            f[i][2048]=ans;         }    LL er=quick(2,tmp,mod);    printf("%d\n",int(er*ans%mod));}void pre(){   fac[0]=1;    for (int i=1;i<=100000;i++)        fac[i]=fac[i-1]*i%mod;    for (int i=0;i<=100000;i++)        facc[i]=quick(fac[i],mod-2,mod);    memset(vis,255,sizeof(vis));    tr[0]=1;vis[1]=0;for (int i=1;i<=11;i++){tr[i]=tr[i-1]*2;vis[tr[i]]=i;}}int main(){   //freopen("1001.in","r",stdin);    pre();    int cas,id=0;    while (scanf("%d",&n),n)        {printf("Case #%d: ",++id);         doit();        }}


0 0