• HDU 4778 Gems Fight!(DP)


    题目链接

    当我放弃的时候过了。sb啊,卡常数!!!

    换了好几个姿势,本来没写预处理,预处理+俩剪枝,尼玛就过了。。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <queue>
      5 using namespace std;
      6 #define INF 0x3f3f3f3f
      7 #define LL __int64
      8 int bag[31][31];
      9 int sum[31];
     10 int dp[1<<21];
     11 int bg[1<<21][11];
     12 int g,b,s;
     13 int temp[31];
     14 int dfs(int x)
     15 {
     16     int maxz = 0,i,j,flag,st;
     17     if(dp[x] != -1)
     18     return dp[x];
     19     for(i = 0;i < b;i ++)
     20     {
     21         if((x&(1<<i)) == 0)
     22         {
     23             flag = 0;
     24             st = 0;
     25             for(j = 0;j < g;j ++)
     26             {
     27                 flag += bg[x|(1<<i)][j]/s - bg[x][j]/s;
     28                 st += sum[j]/s - bg[x|(1<<i)][j]/s;
     29             }
     30             if(flag)
     31             {
     32                 if(maxz >= st + flag) continue;//剪枝就是这两个剪枝
     33                 if(maxz < dfs(x|(1<<i))+flag)
     34                 maxz = dfs(x|(1<<i))+flag;
     35             }
     36             else
     37             {
     38                 if(maxz >= st) continue;//剪枝
     39                 if(maxz < st - dfs(x|(1<<i)))
     40                 maxz = st - dfs(x|(1<<i));
     41             }
     42         }
     43     }
     44     return dp[x] = maxz;
     45 }
     46 int main()
     47 {
     48     int i,j,k,n,num,sp,sa,sb;
     49     while(scanf("%d%d%d",&g,&b,&s)!=EOF)
     50     {
     51         if(g == 0&&b == 0&&s == 0)
     52         break;
     53         for(i = 0;i < (1<<b);i ++)
     54         {
     55             dp[i] = -1;
     56             for(j = 0;j < g;j ++)
     57             bg[i][j] = 0;
     58         }
     59         for(i = 0;i < b;i ++)
     60         {
     61             for(j = 0;j < g;j ++)
     62             {
     63                 bag[i][j] = 0;
     64             }
     65         }
     66         for(j = 0;j < g;j ++)
     67         {
     68             sum[j] = temp[j] = 0;
     69         }
     70         for(i = 0;i < b;i ++)
     71         {
     72             scanf("%d",&n);
     73             for(j = 1;j <= n;j ++)
     74             {
     75                 scanf("%d",&num);
     76                 bag[i][num-1]++;
     77                 sum[num-1] ++;
     78             }
     79         }
     80         for(i = 0;i < (1<<b);i ++)//扯淡的预处理
     81         {
     82             for(j = 0;j < b;j ++)
     83             {
     84                 if(i&(1<<j))
     85                 {
     86                     for(k = 0;k < g;k ++)
     87                     bg[i][k] += bag[j][k];
     88                 }
     89             }
     90         }
     91         sp = 0;
     92         for(i = 0;i < g;i ++)
     93         {
     94             sp += sum[i]/s;
     95         }
     96         sa = dfs(0);
     97         sb = sp - sa;
     98         printf("%d
    ",sa-sb);
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    Oracle 分析函数
    Oracle 增加修改删除字段
    Oracle 重置序列
    End2EndIT
    Hyperledger Fabric SDK use case 1
    云计算中8项核心技术
    Cloud
    JVM Guide
    微信公众平台PHP开发
    在Linux系统环境下修改MySQL的root密码
  • 原文地址:https://www.cnblogs.com/naix-x/p/3416473.html
Copyright © 2020-2023  润新知