• [bzoj4971]记忆中的背包


    为了使得方案的形式较为单一,不妨强制物品体积为1或$ge lceilfrac{w}{2} ceil$,那么假设最终有$x$个1且$ge lceilfrac{w}{2} ceil$的物品体积依次为$a_{1},a_{2},...,a_{n-x}$,不难发现方案数即为$sum_{i=1}^{n-x}{xchoose w-a_{i}}$

    暴力枚举$x$,并不妨再强制方案数恰为$k$(而不是模$p$意义下),此时即选不超过$n-x$个${xchoose i}$使得其和恰为$k$(其中$iin [0,lfloorfrac{w}{2} floor]$,由于$wge 50$不妨变为$in [0,lfloorfrac{x}{2} floor]$,即问题与$w$无关)

    每一次选$i=max_{0le jle 8,{16choose j}le k}j$,由于${xchoose 0}=1$,重复此过程最终总可得到$k$,并考虑所有$kin [0,2cdot 10^{4}]$后可以发现只需要取$x=13$或$14$即可保证有解

    时间复杂度为$o(tn)$,可以通过

    (dark_bzoj上该题似乎没有spj)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 15
     4 vector<int>v;
     5 int t,n,m,x,w,C[N][N];
     6 int main(){
     7     for(int i=0;i<N;i++){
     8         C[i][0]=C[i][i]=1;
     9         for(int j=1;j<i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
    10     }
    11     scanf("%d",&t);
    12     while (t--){
    13         scanf("%d%*d%d",&w,&n);
    14         for(int x=13;x<=14;x++){
    15             m=n;
    16             v.clear();
    17             for(int i=0;i<x;i++)v.push_back(1);
    18             for(int i=(x>>1);i>=0;i--){
    19                 for(int j=0;j<m/C[x][i];j++)v.push_back(w-i);
    20                 m%=C[x][i];
    21             }
    22             if (v.size()<=40){
    23                 printf("%d
    ",(int)v.size());
    24                 for(int i=0;i+1<v.size();i++)printf("%d ",v[i]);
    25                 printf("%d
    ",v.back());
    26                 break;
    27             }
    28         }
    29     }
    30     return 0;
    31 } 
    View Code
  • 相关阅读:
    计划任务和压缩归档
    libevent 源码学习三 —— 基本使用场景和事件流程
    libevent 源码学习二 —— reactor 模式
    libevent 库源码学习
    手动配置固定IP参数vim vim
    软件相关
    写xhttpd服务器时 遇到segmentation fault
    c与c++中输出字符指针和字符串指针的问题
    char * argv[] ,string简析
    传入参数与传出参数
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15359591.html
Copyright © 2020-2023  润新知