zoukankan      html  css  js  c++  java
  • [loj3331]选课

    考虑$P=0$,由于$T-sum_{i=1}^{m}s_{i}le 40$,因此一个第$i$个分类中最多得到$s_{i}+42$的学分,可以对每一类分别背包
    暴力背包复杂度为$o(n^{2})$,但背包实际用到的部分只有$o(40)$个位置,因此考虑直接求某个体积的答案
    先枚举$3$的个数,那么问题相当于求体积为${1,2}$的答案,可以将相邻两个1看作一个2来贪心,预处理出两类的前缀和,再对体积的奇偶性分类讨论
    时间复杂度:预处理$o(nlog n+40n)$,合并$o(40^{2}m)$
    当$P=12$,先对与$P$无关的分类按上述方式处理,那么剩下的问题就有$mle 12$
    对于这些分类,先求出所有没有限制的课程的结果(注意这里的范围要到$[s_{i}-36,s_{i}+42]$),然后$o(2^{P})$暴力枚举这些课程是否选择,复杂度$o(2^{P}40^{2}m+76n)$
    有两个小问题:1.有一组数据不满足$Tge sum_{i=1}^{m}s_{i}$,因此差值需要对0取min;2.最终的和有可能超过$sum_{i=1}^{m}s_{i}+42$,但下标不能太大(否则复杂度不对),将下标对$T-sum_{i=1}^{m}s_{i}$取min即可
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 50004
      4 #define oo 0x3f3f3f3f
      5 map<int,int>mat[N];
      6 map<int,int>::iterator it;
      7 vector<int>vo,ve,w[N],c[N],v[N][4];
      8 int V,n,m,x,y,ans,a[N],s[N],vis[105],p[105],sum[105][105],g[105],f[105],ff[105][105],dp[105];
      9 void init(int k){
     10     vo.clear();
     11     for(int i=0;i+1<v[k][1].size();i+=2)vo.push_back(v[k][1][i]+v[k][1][i+1]);
     12     for(int i=0;i<v[k][2].size();i++)vo.push_back(v[k][2][i]);
     13     sort(vo.begin(),vo.end());
     14     for(int i=0;i+1<vo.size();i++)vo[i+1]+=vo[i];
     15     ve.clear();
     16     for(int i=1;i+1<v[k][1].size();i+=2)ve.push_back(v[k][1][i]+v[k][1][i+1]);
     17     for(int i=0;i<v[k][2].size();i++)ve.push_back(v[k][2][i]);
     18     sort(ve.begin(),ve.end());
     19     for(int i=0;i+1<ve.size();i++)ve[i+1]+=ve[i];
     20 }
     21 int query_12(int k,int x){
     22     if (x<0)return oo;
     23     if (x%2==0){
     24         if (x==0)return 0;
     25         if (vo.size()<x/2)return oo;
     26         return vo[x/2-1];
     27     }
     28     if (!v[k][1].size())return oo;
     29     if (x==1)return v[k][1][0];
     30     if (ve.size()<x/2)return oo;
     31     return ve[x/2-1]+v[k][1][0];
     32 }
     33 int query_123(int k,int x){
     34     int s=0,ans=query_12(k,x);
     35     for(int i=0;i<v[k][3].size();i++){
     36         s+=v[k][3][i];
     37         ans=min(ans,s+query_12(k,x-3*(i+1)));
     38     }
     39     return ans;
     40 }
     41 void merge(){
     42     memset(ff[0],oo,sizeof(ff[0]));
     43     for(int i=0;i<=42;i++)
     44         for(int j=0;j<=42;j++)ff[0][min(i+j,s[0])]=min(ff[0][min(i+j,s[0])],f[i]+dp[j]);
     45     memcpy(dp,ff[0],sizeof(dp));
     46 }
     47 void dfs(int k){
     48     if (k>V){
     49         int tot=0;
     50         for(int i=1;i<=V;i++)
     51             for(int j=1;j<=V;j++)
     52                 if ((vis[i])&&(vis[j])){
     53                     if (sum[i][j]==oo)return;
     54                     tot+=sum[i][j];
     55                 }
     56         for(int i=1;i<=p[0];i++)
     57             for(it=mat[p[i]].begin();it!=mat[p[i]].end();it++)
     58                 if (vis[(*it).second])tot+=c[p[i]][(*it).first];
     59         memcpy(dp,g,sizeof(g));
     60         for(int i=1;i<=p[0];i++){
     61             int ss=0;
     62             for(it=mat[p[i]].begin();it!=mat[p[i]].end();it++)
     63                 if (vis[(*it).second])ss+=w[p[i]][(*it).first];
     64             for(int j=0;j<=42;j++)f[j]=ff[i][j+36-ss];
     65             merge();
     66         }
     67         for(int i=s[0];i<=42;i++)ans=min(ans,tot+dp[i]);
     68         return;
     69     }
     70     vis[k]=0;
     71     dfs(k+1);
     72     vis[k]=1;
     73     dfs(k+1);
     74 }
     75 int main(){
     76     scanf("%d%d",&n,&s[0]);
     77     for(int i=1;i<=n;i++){
     78         scanf("%d%d",&a[i],&s[i]);
     79         for(int j=1;j<=a[i];j++){
     80             scanf("%d%d",&x,&y);
     81             w[i].push_back(x);
     82             c[i].push_back(y);
     83             v[i][x].push_back(y);
     84         }
     85         for(int j=1;j<4;j++)sort(v[i][j].begin(),v[i][j].end());
     86         s[0]-=s[i];
     87     }
     88     s[0]=max(s[0],0);
     89     scanf("%d",&m);
     90     for(int i=1;i<=m;i++){
     91         int p,x1,y1,x2,y2,cc;
     92         scanf("%d%d%d%d%d",&p,&x1,&y1,&x2,&y2);
     93         if (p==3)cc=oo;
     94         else{
     95             scanf("%d",&cc);
     96             if (p==1)cc=-cc;
     97         }
     98         if (!mat[x1][y1-1])mat[x1][y1-1]=++V;
     99         if (!mat[x2][y2-1])mat[x2][y2-1]=++V;
    100         sum[mat[x1][y1-1]][mat[x2][y2-1]]=cc;
    101     }
    102     memset(dp,oo,sizeof(dp));
    103     dp[0]=0;
    104     for(int i=1;i<=n;i++)
    105         if (!mat[i].size()){
    106             init(i);
    107             for(int j=0;j<=42;j++)f[j]=query_123(i,j+s[i]);
    108             merge();
    109         }
    110         else{
    111             p[++p[0]]=i;
    112             for(it=mat[i].begin();it!=mat[i].end();it++){
    113                 x=(*it).first;
    114                 v[i][w[i][x]].erase(lower_bound(v[i][w[i][x]].begin(),v[i][w[i][x]].end(),c[i][x]));
    115             }
    116             init(i);
    117             for(int j=-36;j<=42;j++)ff[p[0]][j+36]=query_123(i,j+s[i]);
    118         }
    119     memcpy(g,dp,sizeof(g));
    120     ans=oo;
    121     dfs(1);
    122     if (ans>=oo)ans=-1;
    123     printf("%d",ans);
    124 }
    View Code
  • 相关阅读:
    -bash: belts.awk: command not found
    PLS-00357: Table,View Or Sequence reference 'SEQ_TRADE_RECODE.NEXTVAL' not allowed in this context
    初识makefile
    proc:基本数据库操作
    ORA-12154: TNS:could not resolve the connect identifier specified
    简单的爬虫
    合并一个文文件夹下的所有Excel文件
    Python 递归读取文件夹内所有文件名(包含子文件夹)
    CSS
    JQ
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13540387.html
Copyright © 2011-2022 走看看