zoukankan      html  css  js  c++  java
  • hdu--1059--多重背包||DP||搜索

    碎碎念-----

      突然 觉得好无聊~~ 还好 只有4天了~~

      直接上题吧~~

        touch  me

      使用多重背包的代码是转自---键盘上的舞者---- 写得特别有想法

      使用dp的代码是porker写的..

      使用搜索的 我一开始是将价值从低到高搜索的 这样TLE了,,因为速度实在是太慢了 假如有arr[k]个 那么我要有arr[k]+1个操作...

      但是 按价值从高到低的搜索 只要遵循 尽量在不到sum/2的时候去搜就是了 有就添加进来...但这个方法的正确性 没有得到证明...

      

     1 #include <iostream>
     2 using namespace std;
     3 int arr[7];
     4 int sum, cnt = 1;
     5 
     6 bool dp[7][120001];
     7 
     8 int main()
     9 {
    10     cin.sync_with_stdio(false);
    11     while (cin >> arr[1])
    12     {
    13         sum = 0;
    14         sum += arr[1];
    15         for (int i = 2; i <= 6; i++)
    16         {
    17             cin >> arr[i];
    18             sum += arr[i] * i;
    19         }
    20         if (!sum)
    21             break;
    22         cout << "Collection #" << cnt++ << ":" << endl;
    23         if (sum & 1) {
    24             cout << "Can't be divided." << endl << endl;
    25             continue;
    26         }
    27         memset(dp, false, sizeof(dp));
    28         dp[0][0] = true;
    29         for (int i = 1; i <= 6; i++) {
    30             for (int j = sum; j >= 0; j--) {
    31                 if (dp[i - 1][j] == false) continue;
    32                 for (int k = 0; k <= arr[i]; k++) {
    33                     if (j + k*i >= sum) break;
    34                     if (dp[i][j + k*i]) break;
    35                     dp[i][j + k*i] = true;
    36                 }
    37             }
    38         }
    39         if (dp[6][sum / 2]) {
    40             cout << "Can be divided." << endl;
    41         }
    42         else {
    43             cout << "Can't be divided." << endl;
    44         }
    45         cout << endl;
    46     }
    47     return 0;
    48 }
    View Code
     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 int dp[100000];
     7 
     8 int main()
     9 {
    10     int a[11],sum,v,i,j,k,cnt,cas = 1;
    11     while(~scanf("%d",&a[1]))
    12     {
    13         sum = a[1];
    14         for(i = 2;i<=6;i++)
    15         {
    16             scanf("%d",&a[i]);
    17             sum+=i*a[i];
    18         }
    19         if(!sum)
    20         break;
    21         printf("Collection #%d:
    ",cas++);
    22         if(sum%2)//总和为奇数,必定不能平分
    23         {
    24             printf("Can't be divided.
    
    ");
    25             continue;
    26         }
    27         v = sum/2;
    28         memset(dp,0,sizeof(dp));
    29         dp[0] = 1;
    30         for(i = 1;i<=6;i++)
    31         {
    32             if(!a[i])
    33             continue;
    34             for(j = 1;j<=a[i];j*=2)//二进制优化
    35             {
    36                 cnt = j*i;
    37                 for(k = v;k>=cnt;k--)
    38                 {
    39                     if(dp[k-cnt])//必须前面的能够放入背包,现在的才能放入背包
    40                     dp[k] = 1;
    41                 }
    42                 a[i]-=j;
    43             }
    44             cnt = a[i]*i;//剩下的
    45             if(cnt)
    46             {
    47                 for(k = v;k>=cnt;k--)
    48                 {
    49                     if(dp[k-cnt])
    50                     dp[k] = 1;
    51                 }
    52             }
    53         }
    54         if(dp[v])
    55         printf("Can be divided.
    
    ");
    56         else
    57         printf("Can't be divided.
    
    ");
    58     }
    59 
    60     return 0;
    61 }
    View Code
     1 #include <iostream>
     2 using namespace std;
     3 int arr[7];
     4 int sum , cnt = 1;
     5 bool flag;
     6 
     7 void dfs( int pos , int cnt )
     8 {
     9     if( cnt*2 == sum )
    10     {
    11         flag = true;
    12         return;
    13     }
    14     if( flag || cnt*2>sum )
    15     {
    16         return;
    17     }                
    18     for( int i = pos ; i>=1 ; i-- )
    19     {
    20         if( arr[i] )
    21         {
    22             if( cnt+i<=sum/2 )
    23             {
    24                 arr[i]--;
    25                 dfs( i , cnt+i );
    26                 if( flag )
    27                     break;
    28             }
    29         }    
    30     }
    31 }
    32 
    33 int main()
    34 {
    35     cin.sync_with_stdio(false);
    36     while( cin >> arr[1] )
    37     {
    38         flag =false;
    39         sum = 0;
    40         sum += arr[1];
    41         for( int i = 2 ; i<=6 ; i++ )
    42         {
    43             cin >> arr[i];
    44             sum += arr[i]*i;
    45         }
    46         if( !sum )
    47             break;
    48         cout << "Collection #"<< cnt++ <<":"<<endl;
    49         if( sum&1 )
    50         {
    51             cout << "Can't be divided." << endl << endl;
    52             continue;
    53         }
    54         dfs( 6 , 0 );
    55         if( flag )
    56             cout << "Can be divided." << endl << endl;
    57         else
    58             cout << "Can't be divided." << endl << endl;
    59     }
    60     return 0;
    61 }
    View Code

    today:

      你看别人说他千般不好 他说过一句没有。

      悲伤的人总是在笑。

    just follow your heart
  • 相关阅读:
    mysql 的事件之 Waiting for table metadata lock
    postgresl 10 的逻辑复制 logical replication 之一
    postgresql 物理备份 pg_rman
    pg_waldump pg_xlogdump 的初步使用
    centos 7 添加 aliyun yum 源、epel源
    pg_dump 迁移 prod 环境的 function 到 uat 环境
    POSTGRESQL 11 BETA 1 RELEASED!
    使用 mtools 搭架 mongodb 的自动化日志分析平台
    将xml转换为PHP数组
    php自动获取字符串编码函数mb_detect_encoding
  • 原文地址:https://www.cnblogs.com/radical/p/3849990.html
Copyright © 2011-2022 走看看