zoukankan      html  css  js  c++  java
  • Codeforces Round #160 (Div. 2) D. Maxim and Restaurant(DP)

    题目链接

    想了挺久,枚举每一件物品,当做关键物品,假设再加这一件物品,就>=c了,把剩下的物品背一下包,dp[i][j]表示i个物品可以组成重量j的个数。

    这样就可以知道前面放i件,后边肯定放n-i-1件,乱搞搞,算double,边乘边算保证不要越界。最后注意,LL和sum <= c的时候情况。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <cmath>
     6 #include <algorithm>
     7 using namespace std;
     8 #define LL __int64
     9 LL dp[2][51][101];
    10 int p[51];
    11 int main()
    12 {
    13     int i,j,k,u,v,n,c,s1,s2,sum;
    14     double ans = 0;
    15     scanf("%d",&n);
    16     sum = 0;
    17     for(i = 1; i <= n; i ++)
    18     {
    19         scanf("%d",&p[i]);
    20         sum += p[i];
    21     }
    22     scanf("%d",&c);
    23     if(sum <= c)
    24     {
    25         printf("%d
    ",n);
    26         return 0;
    27     }
    28     for(i = 1; i <= n; i ++)
    29     {
    30         memset(dp,0,sizeof(dp));
    31         dp[0][0][0] = 1;
    32         s1 = 0;
    33         s2 = 1;
    34         for(j = 1; j <= n; j ++)
    35         {
    36             if(i == j) continue;
    37             for(k = 0; k < j; k ++)
    38             {
    39                 for(u = 0; u <= 100; u ++)
    40                     dp[s2][k][u] = dp[s1][k][u];
    41             }
    42             for(k = 0; k < j; k ++)
    43             {
    44                 for(u = 0; u < 100; u ++)
    45                 {
    46                     if(dp[s1][k][u])
    47                     {
    48                         if(u+p[j] <= 100)
    49                             dp[s2][k+1][u+p[j]] += dp[s1][k][u];
    50                     }
    51                 }
    52             }
    53             swap(s1,s2);
    54         }
    55         for(j = 0; j < c; j ++)
    56         {
    57             if(j + p[i] >= c)
    58             {
    59                 for(k = 0; k < n; k ++)
    60                 {
    61                     if(dp[s1][k][j] == 0) continue;
    62                     double temp = dp[s1][k][j];
    63                     for(u = 1,v = k+1;u <= n-k-1;u ++,v++)
    64                     temp *= u*1.0/v;
    65                     temp /= n;
    66                     if(j + p[i] == c)
    67                     ans += temp*(k+1);
    68                     else
    69                     ans += temp*k;
    70                 }
    71             }
    72         }
    73     }
    74     printf("%lf
    ",ans);
    75     return 0;
    76 }
  • 相关阅读:
    JAVA面试题
    Oracle入门笔记 ——启动进阶
    SQL 基础
    BZOJ 1507 Editor(块状链表)
    BZOJ 1018 堵塞的交通traffic(线段树)
    SPOJ 422 Transposing is Even More Fun(polay计数)
    BZOJ 2754 喵星球上的点名(后缀数组)
    POJ 1568 Find the Winning Move(极大极小搜索)
    Miller-Rabin素数测试学习小计
    Lucas定理学习小记
  • 原文地址:https://www.cnblogs.com/naix-x/p/3355941.html
Copyright © 2011-2022 走看看