动态规划——背包问题变形 收藏


view plaincopy to clipboardprint?
 1 #include <iostream>  
 2 using namespace std;  
 3 #include <sys/time.h>  
 4   
 5 struct timeval t1;  
 6 struct timeval t2;  
 7   
 8 int n ;  
 9 int *a;  
10 int **c;  
11 int min_sub;  
12 int dp(int sum,int t,int m)  
13 {  
14         if(t==0)  
15         {  
16                 if( a[t] <= m)  
17                         return a[t];  
18                 else 
19                         return 0;  
20         }  
21         int tmp1,tmp2;  
22         if(m>=a[t])  
23         {  
24                 tmp2 = dp(sum,t-1,m-a[t]) + a[t];  
25                 tmp1 = dp(sum,t-1,m);  
26                 if(tmp1 > tmp2)  
27                         return tmp1;  
28                 else 
29                         return tmp2;  
30         }  
31         else 
32         {  
33                 return dp(sum,t-1,m);  
34         }  
35 }  
36 int main()  
37 {  
38         gettimeofday(&t1,NULL);  
39         cin >> n;  
40         a = new int[n];  
41         int i = 0;  
42         int j = 0;  
43         for(i = 0;i<n;i++)  
44                 cin>>a[i];  
45         int sum = 0;  
46         for(i=0;i<n;i++)  
47                 sum+=a[i];  
48         cout << "sum=" << sum << endl;  
49         c= new int*[n];  
50         for(i=0;i<n;i++)  
51         {  
52                 c[i] = new int[sum/2+1];  
53                 for(j = 0;j<sum/2+1;j++)  
54                         c[i][j] = -1;  
55         }  
56         cout << dp(sum/2,n-1,sum/2)<<endl;  
57         gettimeofday(&t2,NULL);  
58         cout<< t2.tv_sec*1000+t2.tv_usec-(t1.tv_sec*1000+t1.tv_usec)<<endl;  
59 }  
  1 #include <iostream>
  2 using namespace std;
  3 #include <sys/time.h>
  4
  5 struct timeval t1;
  6 struct timeval t2;
  7
  8 int n ;
  9 int *a;
 10 int **c;
 11 int min_sub;
 12 int dp(int sum,int t,int m)
 13 {
 14         if(t==0)
 15         {
 16                 if( a[t] <= m)
 17                         return a[t];
 18                 else
 19                         return 0;
 20         }
 21         int tmp1,tmp2;
 22         if(m>=a[t])
 23         {
 24                 tmp2 = dp(sum,t-1,m-a[t]) + a[t];
 25                 tmp1 = dp(sum,t-1,m);
 26                 if(tmp1 > tmp2)
 27                         return tmp1;
 28                 else
 29                         return tmp2;
 30         }
 31         else
 32         {
 33                 return dp(sum,t-1,m);
 34         }
 35 }
 36 int main()
 37 {
 38         gettimeofday(&t1,NULL);
 39         cin >> n;
 40         a = new int[n];
 41         int i = 0;
 42         int j = 0;
 43         for(i = 0;i<n;i++)
 44                 cin>>a[i];
 45         int sum = 0;
 46         for(i=0;i<n;i++)
 47                 sum+=a[i];
 48         cout << "sum=" << sum << endl;
 49         c= new int*[n];
 50         for(i=0;i<n;i++)
 51         {
 52                 c[i] = new int[sum/2+1];
 53                 for(j = 0;j<sum/2+1;j++)
 54                         c[i][j] = -1;
 55         }
 56         cout << dp(sum/2,n-1,sum/2)<<endl;
 57         gettimeofday(&t2,NULL);
 58         cout<< t2.tv_sec*1000+t2.tv_usec-(t1.tv_sec*1000+t1.tv_usec)<<endl;
 59 } 

view plaincopy to clipboardprint?
 1 #include <iostream>  
 2 using namespace std;  
 3 #include <sys/time.h>  
 4   
 5 struct timeval t1,t2;  
 6 int n ;  
 7 int *a;  
 8 int **c;  
 9 int min_sub;  
10 int dp(int sum,int t,int m)  
11 {  
12         if(c[t][m] !=-1)  
13                 return c[t][m];  
14         if(t==0)  
15         {  
16                 if( a[t] <= m)  
17                         return a[t];  
18                 else      
19                         return 0;  
20         }                 
21         int tmp1,tmp2;  
22         if(m>=a[t])  
23         {  
24                 tmp2 = dp(sum,t-1,m-a[t]) + a[t];  
25                 tmp1 = dp(sum,t-1,m);  
26                 if(tmp1 > tmp2)  
27                         c[t][m]=tmp1;  
28                 else      
29                         c[t][m] = tmp2;  
30                 return c[t][m];   
31         }         
32         else 
33         {  
34                 c[t][m] = dp(sum,t-1,m);  
35                 return c[t][m];  
36         }         
37 }         
38 int main()  
39 {  
40         gettimeofday(&t1,NULL);  
41         cin >> n;  
42         a = new int[n];  
43         int i = 0;  
44         int j = 0;  
45         for(i = 0;i<n;i++)  
46                 cin>>a[i];  
47         int sum = 0;  
48         for(i=0;i<n;i++)  
49                 sum+=a[i];  
50         cout << "sum=" << sum << endl;  
51         c= new int*[n];  
52         for(i=0;i<n;i++)  
53         {  
54                 c[i] = new int[sum/2+1];  
55                 for(j = 0;j<sum/2+1;j++)  
56                         c[i][j] = -1;  
57         }  
58         cout << dp(sum/2,n-1,sum/2)<<endl;  
59         gettimeofday(&t2,NULL);  
60         cout<< (t2.tv_sec*1000+t2.tv_usec)-(t1.tv_sec*1000+t1.tv_usec)<<endl;  
61 }  
  1 #include <iostream>
  2 using namespace std;
  3 #include <sys/time.h>
  4
  5 struct timeval t1,t2;
  6 int n ;
  7 int *a;
  8 int **c;
  9 int min_sub;
 10 int dp(int sum,int t,int m)
 11 {
 12         if(c[t][m] !=-1)
 13                 return c[t][m];
 14         if(t==0)
 15         {
 16                 if( a[t] <= m)
 17                         return a[t];
 18                 else   
 19                         return 0;
 20         }              
 21         int tmp1,tmp2;
 22         if(m>=a[t])
 23         {
 24                 tmp2 = dp(sum,t-1,m-a[t]) + a[t];
 25                 tmp1 = dp(sum,t-1,m);
 26                 if(tmp1 > tmp2)
 27                         c[t][m]=tmp1;
 28                 else   
 29                         c[t][m] = tmp2;
 30                 return c[t][m];
 31         }      
 32         else
 33         {
 34                 c[t][m] = dp(sum,t-1,m);
 35                 return c[t][m];
 36         }      
 37 }      
 38 int main()
 39 {
 40         gettimeofday(&t1,NULL);
 41         cin >> n;
 42         a = new int[n];
 43         int i = 0;
 44         int j = 0;
 45         for(i = 0;i<n;i++)
 46                 cin>>a[i];
 47         int sum = 0;
 48         for(i=0;i<n;i++)
 49                 sum+=a[i];
 50         cout << "sum=" << sum << endl;
 51         c= new int*[n];
 52         for(i=0;i<n;i++)
 53         {
 54                 c[i] = new int[sum/2+1];
 55                 for(j = 0;j<sum/2+1;j++)
 56                         c[i][j] = -1;
 57         }
 58         cout << dp(sum/2,n-1,sum/2)<<endl;
 59         gettimeofday(&t2,NULL);
 60         cout<< (t2.tv_sec*1000+t2.tv_usec)-(t1.tv_sec*1000+t1.tv_usec)<<endl;
 61 }  view plaincopy to clipboardprint?
 1 #include <iostream>  
 2 using namespace std;  
 3 #include <sys/time.h>  
 4   
 5 struct timeval t1,t2;  
 6 int n ;  
 7 int *a;  
 8 int **c;  
 9 int min_sub;  
10 int dp(int sum)  
11 {  
12         int i = 0;  
13         int j = 0;  
14         for(i =1;i<n+1;i++)  
15                 for(j = 1;j<=sum;j++)  
16                 {  
17                         if(a[i] >j)  
18                         {  
19                                 c[i][j] = c[i-1][j];  
20                         }  
21                         else 
22                         {  
23                                 int tmp1 = c[i-1][j];  
24                                 int tmp2 = c[i-1][j-a[i]] +a[i];  
25                                 c[i][j] = tmp1>tmp2?tmp1:tmp2;  
26                         }  
27                 }  
28         return c[n][sum];  
29 }  
30 int main()  
31 {  
32         gettimeofday(&t1,NULL);  
33         cin >> n;  
34         a = new int[n];  
35         int i = 0;  
36         int j = 0;  
37         for(i = 0;i<n;i++)  
38                 cin>>a[i];  
39         int sum = 0;  
40         for(i=0;i<n;i++)  
41                 sum+=a[i];  
42         cout << "sum=" << sum << endl;  
43         c= new int*[n+1];  
44         for(i=0;i<n+1;i++)  
45         {  
46                 c[i] = new int[sum/2+1];  
47                 for(j = 0;j<sum/2+1;j++)  
48                         c[i][j] = 0;  
49         }  
50         cout << dp(sum/2)<<endl;  
51         gettimeofday(&t2,NULL);  
52         cout<< (t2.tv_sec*1000+t2.tv_usec)-(t1.tv_sec*1000+t1.tv_usec)<<endl;  
53 }  
  1 #include <iostream>
  2 using namespace std;
  3 #include <sys/time.h>
  4
  5 struct timeval t1,t2;
  6 int n ;
  7 int *a;
  8 int **c;
  9 int min_sub;
 10 int dp(int sum)
 11 {
 12         int i = 0;
 13         int j = 0;
 14         for(i =1;i<n+1;i++)
 15                 for(j = 1;j<=sum;j++)
 16                 {
 17                         if(a[i] >j)
 18                         {
 19                                 c[i][j] = c[i-1][j];
 20                         }
 21                         else
 22                         {
 23                                 int tmp1 = c[i-1][j];
 24                                 int tmp2 = c[i-1][j-a[i]] +a[i];
 25                                 c[i][j] = tmp1>tmp2?tmp1:tmp2;
 26                         }
 27                 }
 28         return c[n][sum];
 29 }
 30 int main()
 31 {
 32         gettimeofday(&t1,NULL);
 33         cin >> n;
 34         a = new int[n];
 35         int i = 0;
 36         int j = 0;
 37         for(i = 0;i<n;i++)
 38                 cin>>a[i];
 39         int sum = 0;
 40         for(i=0;i<n;i++)
 41                 sum+=a[i];
 42         cout << "sum=" << sum << endl;
 43         c= new int*[n+1];
 44         for(i=0;i<n+1;i++)
 45         {
 46                 c[i] = new int[sum/2+1];
 47                 for(j = 0;j<sum/2+1;j++)
 48                         c[i][j] = 0;
 49         }
 50         cout << dp(sum/2)<<endl;
 51         gettimeofday(&t2,NULL);
 52         cout<< (t2.tv_sec*1000+t2.tv_usec)-(t1.tv_sec*1000+t1.tv_usec)<<endl;
 53 }  给定一个正整数的集合A={a1,a2,….,an},是否可以将其分割成两个子集合,使两个子集合的数加起来的和相等。  
  输出:例:A   =   {   1,   3,   8,   4,   10}  
  可以分割:{1,   8,   4}   及   {3,   10}

可以转化成背包问题:

1,首先算出所有元素的和sum。

2,计算不超过sum/2但最接近sum/2的元素的选择。(背包容量为suj/2)

上面给出的DP和递归的实现:

(1)迭代递归:用时104529 us

(2)记忆化递归(记忆化DP):用时318601 us

(3)直接递归:用时634060 us

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clearriver/archive/2009/08/14/4447523.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值