您的位置:首页 > 其它

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

2009-09-13 22:10 513 查看
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
;
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*
;
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
;
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*
;
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
;
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*
;
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
;
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*
;
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
[sum];
29 }
30 int main()
31 {
32 gettimeofday(&t1,NULL);
33 cin >> n;
34 a = new int
;
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
[sum];
29 }
30 int main()
31 {
32 gettimeofday(&t1,NULL);
33 cin >> n;
34 a = new int
;
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: