JZOJ 4224. 食物

题目

Description

 

Input

Output

 

Sample Input

4
1 1 7
14 2 1
1 2 2
1 1 10
10 10 1
5 7 2
5 3 34
1 4 1
9 4 2
5 3 3
1 3 3
5 3 2
3 4 5
6 7 5
5 3 8
1 1 1
1 2 1
1 1 1

Sample Output

4
14
12
TAT
 

Data Constraint

分析

  • 首先,很显然是两个多重背包

  • 但是我们发现如果裸着跑的话一定会TLE
  • 所以我们要尝试优化背包
  • 我们这里采用二进制优化
  • 首先我们能知道
  • 二进制能组成任何一个数
  • 如果我们将背包的个数k拆解出来就好了
  • 拆成 1,2,4,8,16……
  • 剩下的就再DP一次就好了
  • 简单讲就是就是拆成二进制
  • 比如说数量为3 不就是1+2吗
  • 所以我们只需要DP一下1,2就能得到答案了
  • 时间复杂度大大减少

 

代码

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 int f[50010],g[50010];
 6 void dp(int x,int y) 
 7 { 
 8    for (int i=20000;i>=x;i--) 
 9       f[i]=max(f[i],f[i-x]+y); 
10 }
11 void dp1(int x,int y) 
12 { 
13    for (int i=50000;i>=x;i--) 
14       g[i]=max(g[i],g[i-x]+y); 
15 }
16 int main ()
17 {
18     ios::sync_with_stdio(false);
19     int T;
20     cin>>T;
21     for (int i=1;i<=T;i++)
22     {
23         int n,m,p;
24         cin>>n>>m>>p;
25         memset(f,0,sizeof(f));
26         memset(g,0,sizeof(g));
27         for (int i=1,t,u,v;i<=n;i++)
28         {
29             cin>>t>>u>>v;
30             for (int j=1;j<=v;v-=j,j*=2)
31                dp(u*j,t*j);
32             if (v) dp(u*v,t*v);
33         }
34         for (int i=1,x,y,z;i<=m;i++)
35         {
36             cin>>x>>y>>z;
37             for (int j=1;j<=z;z-=j,j*=2)
38                dp1(y*j,x*j);
39             if (z) dp1(y*z,x*z);
40         }
41         int ans=0;
42         for (int i=1;i<=50000;i++)
43            if (f[g[i]]>=p) {
44                   ans=i;
45                   break;
46            }
47         if (ans) cout<<ans<<endl;
48         else
49            cout<<"TAT"<<endl;
50     }
51 }

 

猜你喜欢

转载自www.cnblogs.com/zjzjzj/p/10324877.html