UVa 10280 Old Wine Into New Bottles / 完全背包

转载 2013年12月05日 18:00:59

转自http://blog.csdn.net/yan_____/article/details/8671147

1、这道题如果直接把每个酒瓶的可用容量来做完全背包的话会超时,但是由最低的容量不低于95%,最高的容量不超过99%,由于容量的连续性有一些规律可循,可藉此优化:

   考虑任意一种瓶子能够将酒全装满的情况,最小容量min,最大容量max,只要酒的体积x在[min,max]|[2*min,2*max]|……[k*min,k*max]的范围内就能完全装满,而max比min大,倍乘后单个区间长度会越来越长,而区间左端保持等距,右端距离越来越远,每当增加一个k,上一区间的右端点与当前区间的左端点距离就会减小(max-min),所以当(k+1)增加到(min*2-max)/(max-min)时各个区间就会相连,即min*(k+1)>max*k,得到k<min/(max-min),我们要求的边界就是k*min<min*min/(max-min),在这之后x都能装满

举个例子min=95,max=99

95     99
190     198
285     297
380     396
475     495
570     594
665     693
760     792
855     891
950     990
1045     1089
1140     1188
1235     1287
1330     1386
1425     1485
1520     1584
1615     1683
1710     1782
1805     1881
1900     1980
1995     2079
2090     2178
2185     2277
2280     2376//这里开始相连,2280是边界
2375     2475
2470     2574
2565     2673
2660     2772
2755     2871
2850     2970
2945     3069
3040     3168
3135     3267
3230     3366
3325     3465
3420     3564

2、瓶子最多有100个,全部满足的容量可能会有重叠,如果忽视重复容量会超时

#include<stdio.h>
#include<string.h>
#define s 2500
#define maxn 450000
int v;
int dp[maxn],vis[4600],c[4600];
int a[110],b[110];
int main()
{
    int i,j,k,l,n,m;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        k=1<<30;
        scanf("%d %d",&v,&n);
        v=v*1000;
        dp[0]=1;
        for(i=0;i<n;i++)
        {
            scanf("%d %d",&a[i],&b[i]);
            if(k>a[i]*a[i]/(b[i]-a[i]))
                k=a[i]*a[i]/(b[i]-a[i]);
        }
        if(v>=k)
        {
            printf("0\n");
            if(t)
            printf("\n");
        }
        else
        {
            m=0;
            memset(vis,0,sizeof(vis));
            memset(dp,0,sizeof(dp));
            for(i=0;i<n;i++)
            {
                for(j=a[i];j<=b[i];j++)
                {
                    if(!vis[j])
                    {
                        c[m++]=j;
                        vis[j]=1;
                    }
                }
            }
            dp[0]=1;
            for(i=0;i<m;i++)
            {
                for(j=c[i];j<=v;j++)
                    if(dp[j-c[i]]==1)
                        dp[j]=1;
            }
            for(i=v;i>=0;i--)
            {
                if(dp[i])
                    break;
            }
            printf("%d\n",v-i);
            if(t)
            printf("\n");
        }
    }
    return 0;

}


 

相关文章推荐

uva10280(完全背包+剪枝)

题意: 有n升的酒(n*1000毫升);然后有m种瓶子,每种瓶子有最小装酒量,和最大装酒量(单位:毫升),瓶子数量不限. 问最少剩下多少酒不能装进去. 思路: 我们可以把酒瓶子分解,比...

uva 10280(完全背包)

题意:有wine L的酒要放到n个瓶子里,每个瓶子最少和最多放多少毫升酒给出,如果瓶子是无限多的,问酒最后最少剩余多少毫升。 题解:相当于完全背包问题,f[i]表示imL的酒最少剩余多少,因为瓶子的...

UVA 10306 e-Coins 电子硬币 完全背包

题意:一种新的硬币,它的价值的计算方法为sqrt(x*x+y*y),x和y为所有硬币的对应的价值的和,求出最少需要几个硬币能构成总面值s。 完全背包,dp[i][j]表示达到x为i,y为j时需要的最...
  • hcbbt
  • hcbbt
  • 2013年11月08日 15:13
  • 1142

【解题报告】uva357_Let Me Count The Ways(让我来数数方案, dp, 完全背包)

357 - Let Me Count The Ways Time limit: 3.000 seconds  Let Me Count The Ways  ...

完全背包问题UVA147

要考试了,实验班一直是我的愿望,虽然现在知道自己估计是上不了可还是想试试毕竟努力了那么久Dollars New Zealand currency consists of $100, $50, $20,...

uva 10404 Bachet's Game (完全背包+博弈)

uva 10404 Bachet’s GameBachet’s game is probably known to all but probably not by this name. Initial...

UVA 147 Dollars (完全背包)

UVA 147 Dollars (完全背包) http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=sh...

UVa 10465 Homer Simpson(DP 完全背包)

 题意 霍默辛普森吃汉堡  有两种汉堡  一中吃一个需要m分钟  另一种吃一个需要n分钟  他共有t分钟时间    要我们输出他在尽量用掉所有时间的前提下最多能吃多少个汉堡  如果时间无法用完...
  • acvay
  • acvay
  • 2014年08月23日 09:52
  • 685

UVA 10465 —— 完全背包

10465 - Homer Simpson Time limit: 3.000 seconds Return of the Aztecs Problem C: Homer Si...
  • zkzxmzk
  • zkzxmzk
  • 2013年11月07日 14:00
  • 672

UVA - 147 Dollars (完全背包 入门题)

完全背包的入门题。有11种硬币,多组cases,每组case给出一个总价格n,问n可以有多少种方式通过这些硬币组合起来。...
  • hmc0411
  • hmc0411
  • 2017年10月30日 22:51
  • 17
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVa 10280 Old Wine Into New Bottles / 完全背包
举报原因:
原因补充:

(最多只允许输入30个字)