背包问题

来源:互联网 发布:魔力鸭淘宝旗舰店 编辑:程序博客网 时间:2024/06/12 21:12

题意:

给定两串数字,有正有服,求出最大和,且这个和的状态下满足任一边都不为负。


思路:

dp。

说是背包,但是其实完全不懂背包的也可以做出来。

本质就是用dp数组来记录状态,然后依次增加状态和更新而已。。

值得注意的就是对负值平移成非负的。



[cpp] view plaincopy
  1. #include<iostream>  
  2. #include<stdio.h>  
  3. #include<string.h>  
  4. #include<algorithm>  
  5. #define Max(a,b) ((a)>(b)?(a):(b))  
  6. #define Min(a,b) ((a)<(b)?(a):(b))  
  7. using namespace std;  
  8. const int N=105;  
  9. const int ost=100000;  
  10. const int inf=(1<<30);  
  11. int n,m;  
  12. int d[2*ost+5];  
  13. struct Node  
  14. {  
  15.     int s,f;  
  16. }a[N];  
  17. void solve()  
  18. {  
  19.     memset(d,0,sizeof(d));  
  20.     d[ost]=ost;  
  21.     int l=ost,r=ost;  
  22.     for(int i=1;i<=n;i++)  
  23.     {  
  24.         int s=a[i].s;  
  25.         int f=a[i].f;  
  26.         if(s>0)  
  27.         {  
  28.             for(int j=r;j>=l;j--)  
  29.             {  
  30.                 if(d[j])  
  31.                 {  
  32.                     d[j+s]=Max(d[j]+f,d[j+s]);  
  33.                     r=Max(r,j+s);  
  34.                 }  
  35.             }  
  36.         }  
  37.         else  
  38.         {  
  39.             for(int j=l;j<=r;j++)  
  40.             {  
  41.                 if(d[j])  
  42.                 {  
  43.                     d[j+s]=Max(d[j]+f,d[j+s]);  
  44.                     l=Min(j+s,l);  
  45.                 }  
  46.             }  
  47.         }  
  48.     }  
  49.     int ans=0;  
  50.     for(int i=ost;i<=r;i++)  
  51.       if(d[i]&&d[i]>=ost)  
  52.       {  
  53.         ans=Max(ans,d[i]+i-2*ost);  
  54.       }  
  55.     printf("%d\n",ans);  
  56. }  
  57. int main()  
  58. {  
  59.     scanf("%d",&n);  
  60.     for(int i=1;i<=n;i++)  
  61.     {  
  62.         scanf("%d%d",&a[i].s,&a[i].f);  
  63.     }  
  64.     solve();  
  65.     return 0;  
  66. }  
0 0
原创粉丝点击