• 2015_6


    C - Cards UVA 12369

    好题,有一副顺序随机的扑克牌,一张张翻开,问至少c,d,h,s张黑桃红心草花方片的期望要翻开的张数。其中两张鬼牌可以代替任意一种花色,当翻到鬼牌时,鬼牌要选择变成一种花色使得期望值最小,并且选完之后这张鬼牌就不能再变化了。两张鬼牌都一样且互不影响。

    深搜记忆化dp,dp[a][b][c][d][e][f]存 从 a张黑桃 b张红心 c张草花 d张方片ef状态到符合题意的要求还需要翻的次数 的期望值, e 表示大鬼状态,f表示小鬼状态,e和f 为0表示未翻开,e和f==1,2,3,4,分别表示这张鬼变成某种颜色。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int M=16;
     5 double dp[M][M][M][M][8][8];
     6 int s[8];
     7 double dfs(int a,int b,int c,int d,int e,int f){
     8     double& tmp=dp[a][b][c][d][e][f];
     9     if(tmp!=-1) return tmp;
    10     if(a+(e==1)+(f==1)>=s[0]&&b+(e==2)+(f==2)>=s[1]&&c+(e==3)+(f==3)>=s[2]&&d+(e==4)+(f==4)>=s[3]){
    11         tmp=0;
    12         return tmp;
    13     }
    14     int tot=0;
    15     tot+=13-a;
    16     tot+=13-b;
    17     tot+=13-c;
    18     tot+=13-d;
    19     tot+=(e==0);
    20     tot+=(f==0);
    21     double ans=1;
    22     if(a<13){
    23         ans+=(13.0-a)/tot*dfs(a+1,b,c,d,e,f);
    24     }
    25     if(b<13){
    26         ans+=(13.0-b)/tot*dfs(a,b+1,c,d,e,f);
    27     }
    28     if(c<13){
    29         ans+=(13.0-c)/tot*dfs(a,b,c+1,d,e,f);
    30     }
    31     if(d<13){
    32         ans+=(13.0-d)/tot*dfs(a,b,c,d+1,e,f);
    33     }
    34     if(!e){
    35         double sma=dfs(a,b,c,d,1,f);
    36         for(int i=2;i<5;i++){
    37             sma=min(sma,dfs(a,b,c,d,i,f));
    38         }
    39         ans+=1.0/tot*sma;
    40     }
    41     if(!f){
    42         double sma=dfs(a,b,c,d,e,1);
    43         for(int i=2;i<5;i++){
    44             sma=min(sma,dfs(a,b,c,d,e,i));
    45         }
    46         ans+=1.0/tot*sma;
    47     }
    48     tmp=ans;
    49     return tmp;
    50 }
    51 int main(){
    52     int t,cas=1;
    53     while(~scanf("%d",&t)){
    54         while(t--){
    55             int sum=0;
    56             for(int i=0;i<4;i++){
    57                 scanf("%d",&s[i]);
    58                 if(s[i]>13) sum+=s[i]-13;
    59             }
    60             printf("Case %d: ",cas++);
    61             if(sum>2){
    62                 puts("-1.000");
    63                 continue;
    64             }
    65             for(int i=0;i<14;i++){
    66                 for(int j=0;j<14;j++){
    67                     for(int x=0;x<14;x++){
    68                         for(int y=0;y<14;y++){
    69                             for(int a=0;a<5;a++){
    70                                 for(int b=0;b<5;b++){
    71                                     dp[i][j][x][y][a][b]=-1;
    72                                 }
    73                             }
    74                         }
    75                     }
    76                 }
    77             }
    78             printf("%.3f
    ",dfs(0,0,0,0,0,0));
    79         }
    80     }
    81     return 0;
    82 }
    View Code

    B - Candles UVA 12368

    题意是0123456789这10个数字,每一个可选可不选,最后问最少选几个可构成输入n个数字,如果个数相同则选择倒序的值小的选法。构成一个数字的方法有两种,一种是直接由所选数字构成,一种是构成两个数字之和是输入的数字。

    2进制枚举+预处理 2的10次方表示每一位选或者不选

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<vector>
      4 #include<algorithm>
      5 #define mt(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 int a[16],digit[16],len[128];
      8 vector<int> sta[128];
      9 void add(int x){
     10     while(x){
     11         digit[x%10]++;
     12         x/=10;
     13     }
     14 }
     15 bool judge(){
     16     for(int i=0;i<10;i++){
     17         if(digit[i]>1) return false;
     18     }
     19     return true;
     20 }
     21 int get(){
     22     int res=0;
     23     for(int i=9;i>=0;i--){
     24         res<<=1;
     25         res|=digit[i];
     26     }
     27     return res;
     28 }
     29 bool test(int x){
     30     mt(digit,0);
     31     add(x);
     32     return judge();
     33 }
     34 bool test(int x,int y){
     35     mt(digit,0);
     36     add(x);
     37     add(y);
     38     return judge();
     39 }
     40 int getone(int x){
     41     int res=0;
     42     while(x){
     43         if(x&1) res++;
     44         x>>=1;
     45     }
     46     return res;
     47 }
     48 int main(){
     49     for(int i=1;i<=100;i++){
     50         sta[i].clear();
     51     }
     52     for(int i=1;i<=100;i++){
     53         if(test(i)){
     54             sta[i].push_back(get());
     55         }
     56         for(int j=1;j+j<=i;j++){
     57             if(test(j,i-j)){
     58                 sta[i].push_back(get());
     59             }
     60         }
     61     }
     62     for(int i=1;i<=100;i++){
     63         sort(sta[i].begin(),sta[i].end());
     64         len[i]=unique(sta[i].begin(),sta[i].end())-sta[i].begin();
     65     }
     66     int n,cas=1,big=1<<10;
     67     while(~scanf("%d",&n),n){
     68         for(int i=0;i<n;i++){
     69             scanf("%d",&a[i]);
     70         }
     71         int ans_cnt=11,ans_sta=0x3f3f3f3f;
     72         for(int i=0;i<big;i++){
     73             int cnt=getone(i);
     74             if(cnt>ans_cnt) continue;
     75             if(cnt==ans_cnt&&i>ans_sta) continue;
     76             bool ok=true;
     77             for(int j=0;j<n;j++){
     78                 bool flag=false;
     79                 for(int k=0;k<len[a[j]];k++){
     80                     int his=sta[a[j]][k];
     81                     if((i&his)==his){
     82                         flag=true;
     83                         break;
     84                     }
     85                 }
     86                 if(!flag){
     87                     ok=false;
     88                     break;
     89                 }
     90             }
     91             if(ok){
     92                 if(ans_cnt>cnt){
     93                     ans_cnt=cnt;
     94                     ans_sta=i;
     95                     continue;
     96                 }
     97                 ans_sta=min(ans_sta,i);
     98             }
     99         }
    100         printf("Case %d: ",cas++);
    101         for(int i=9;i>=0;i--){
    102             if(ans_sta&(1<<i)){
    103                 printf("%d",i);
    104             }
    105         }
    106         puts("");
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    Java简单游戏开发之碰撞检测
    Android应用程序在新的进程中启动新的Activity的方法和过程分析
    Android应用程序组件Content Provider的共享数据更新通知机制分析
    Android应用程序组件Content Provider在应用程序之间共享数据的原理分析
    VS2005检查内存泄露的简单方法
    iOS如何让xcode自动检查内存泄露
    wf
    VC++ListBox控件的使用
    textoverflow:ellipsis溢出文本显示省略号的详细方法
    VC编写代码生成GUID并转换为CString字符串
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/4387746.html
Copyright © 2020-2023  润新知