zoukankan      html  css  js  c++  java
  • Codeforces 580D-Kefa and Dishes(状压DP)

    原题链接:http://codeforces.com/problemset/problem/580/D

    题意:在n个数字中有顺序地选择m个数字,每个数字对应有个值ai,每取一个数字答案加上ai,并且存在k个关系:x y c,如果x恰好排在y的前面,那么答案再加上ci的值。输出最大值。

    思路:状压dp。dp[i][j]中,i是已经选了若干个数的情况,j是最后一个被选取的数,i从选取1个到m个枚举下去,j从第1个数到第n个数进行枚举就能得到答案。

    AC代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 typedef long long LL;
     6 LL a[20],d[20][20],pos[20];
     7 LL dp[1<<19][20]; 
     8 int main()
     9 {
    10     pos[0]=1;
    11     for(int i=1;i<=19;i++) pos[i]=pos[i-1]<<1;
    12     memset(dp,0, sizeof(dp));
    13     memset(d, 0, sizeof(d));
    14     int n,m,k,x,y,c;
    15     scanf("%d %d %d", &n, &m, &k);
    16     for(int i=0;i<n;i++) scanf("%I64d", a+i);
    17     for(int i=0;i<k;i++){
    18         scanf("%d %d %d",&x, &y, &c);
    19         x--,y--;
    20         d[x][y]=c;
    21     }
    22     int num;
    23     for(int i=0;i<n;i++) dp[pos[i]][i]=a[i];
    24     
    25     for(int t=1;t<m;t++){
    26         for(int i=0;i<n;i++){
    27             for(int j=0;j<pos[n];j++){
    28                 if(j&pos[i]) continue;
    29                 
    30                 num=0;//cout<<'*'<<endl;
    31                 k=j;
    32                 while(k){
    33                     if(k&1)
    34                         num++;
    35                     k>>=1;
    36                 }        
    37                 if(num!=t) continue;
    38                 
    39                 for(int s=0;s<n;s++)
    40                     if(s!=i&&(j&pos[s])){
    41                         dp[j|pos[i]][i]=max(dp[j|pos[i]][i], dp[j][s]+d[s][i]+a[i]);
    42                         //cout<<s<<' '<<j<<' '<<i<<' '<<d[s][i]<<' '<<dp[j|pos[i]][i]<<endl;
    43                     }
    44                     
    45             }
    46         }
    47     }
    48     
    49     LL ans=0;
    50     for(int i=0;i<pos[n];i++){
    51         num=0;
    52         k=i;
    53         while(k){
    54             if(k&1)    
    55                 num++;
    56             k>>=1;
    57         }
    58         if(num!=m) continue;
    59         
    60         for(int j=0;j<n;j++) if(pos[j]&i) ans=max(ans, dp[i][j]);
    61     }
    62     printf("%I64d
    ", ans);
    63     return 0;
    64 }
  • 相关阅读:
    javascript打开本地应用
    SDUT OJ -2892 A
    恳请CSDN的活动可以落实
    中国银联mPOS通用技术安全分析和规范解读
    UNIX环境编程学习——反思认识
    STM32F407VG (五)定时器
    请求的链式处理——责任链模式
    Shredding Company (hdu 1539 dfs)
    十天精通CSS3(6)
    十天精通CSS3(5)
  • 原文地址:https://www.cnblogs.com/MasterSpark/p/7464979.html
Copyright © 2011-2022 走看看