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 }

 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:\n",cas++);
22         if(sum%2)//总和为奇数,必定不能平分
23         {
24             printf("Can‘t be divided.\n\n");
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.\n\n");
56         else
57         printf("Can‘t be divided.\n\n");
58     }
59
60     return 0;
61 }

 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 }

today:

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

  悲伤的人总是在笑。

hdu--1059--多重背包||DP||搜索

时间: 2024-08-07 16:46:21

hdu--1059--多重背包||DP||搜索的相关文章

HDU 1059 多重背包+二进制优化

Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16909    Accepted Submission(s): 4729 Problem Description Marsha and Bill own a collection of marbles. They want to split the collection

hdu 1059 (多重背包) Dividing

这里;http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意是有价值分别为1,2,3,4,5,6的商品各若干个,给出每种商品的数量,问是否能够分成价值相等的两份. 联想到多重背包,稍微用二进制优化一下.(最近身体不适,压力山大啊) 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define inf 70000 5 using namespace s

hdu 1059 多重背包

题意:价值分别为1,2,3,4,5,6的物品个数分别为a[1],a[2],a[3],a[4],a[5],a[6],问能不能分成两堆价值相等的. 解法:转化成多重背包 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 7 int dp[120010]; 8 int a[10]; 9 10 int

hdu 1171 Big Event in HDU(母函数|多重背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意:有n种物品,给出每种物品的价值和数目,要将这些物品尽可能的分成相等的两份A和B且A>=B ,输出A,B. 母函数可以过,但感觉最直接的方法应该是多重背包. 母函数的话,也是按总价值的一半求,从一半到小枚举,直到找到系数不为0的就是B. #include <stdio.h> #include <iostream> #include <map> #include <

hdu 5445 多重背包

Food Problem Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1243    Accepted Submission(s): 368 Problem Description Few days before a game of orienteering, Bell came to a mathematician to sol

ACM学习历程—HDU 1059 Dividing(dp &amp;&amp; 多重背包)

Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. This would be easy if all the marbles had the same value, because then they could just spl

hdu 2191 多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

http://acm.hdu.edu.cn/showproblem.php?pid=2191 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的选拔 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17930    Accepted

HDU1171--Big Event in HDU(多重背包)

Big Event in HDU   Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1139 Accepted Submission(s): 444 Problem Description Nowadays, we all know that Computer College is the biggest department in HD

HDU 1171 Big Event in HDU【多重背包】

大意:有n个物品,告诉你每个物品的价值问能否分成价值a.b两份使{a > b  && a + b == 总价值  && a - b尽量小} 分析:多重背包 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 55; 7 const int INF = 1000000