NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]

我只能说,珍爱生命,远离卡常数的题。。。感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,,

哈罗哈的大披萨 【淡蓝】

时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 73            测试通过 : 9

描述

热风哈罗哈(三牌楼)店正在搞活动:他们将提供一个大披萨给第一个告诉他们以下信息的人:一次购买任一种披萨,哪种单位面积的价格最低。问题初步想一想,好像是这么解决:“对于每个披萨计算平均价格,那么最小值就是答案了。”

但是,这个问题不是这么简单,因为在热风哈罗哈店里:对某些披萨,是送打折优惠券的,凭这些优惠券可以得到另一个便宜些甚至差点的披萨,这些优惠券可合并使用。披萨必须一个接一个的买,不可能使用优惠券对一个已买的披萨打折。你能第一个解决这个问题,得到大披萨吗?

输入

输入文件包含几个测试用例。每个测试用例包括:

l       1行:一个数m,为热风哈罗哈提供披萨数目。当m=0时输入终止。一般1 ≤ m ≤ 15。

l       随后的m 行描述每个披萨。每一行描述披萨i (1 ≤ i ≤ m) ,开始3个整数pi, ai 和 ni 表示披萨的价格、面积、和购买它时得到的打折优惠券数目,1 ≤ pi ≤ 10000, 1 ≤ ai ≤ 10000 , 0 ≤ ni < m。

l       随后是ni 对整数xi,j 和 yi,j 表示你得到打折的披萨序号xi,j (1 ≤ xi,j ≤ m, xi,j ≠ i) 以及买披萨xi,j得到的折扣yi,j,以百分比表示(1 ≤ yi,j≤ 50)。可以假设对于每个i ,xi,j 两两不同。

输出

对于每个测试用例:

打印一行,为通过一次购买任何一种披萨所能得到的单位面积最低价钱. 四舍五入到小数点后4位。

注意到你能组合任意数目的打折优惠券:对于价格为10的披萨和两个折扣为50和20的优惠券,你将只需支付10 * 0.8 * 0.5 = 4单位的钱。

样例输入

1
80 30 0
2
200 100 1 2 50
200 100 0
5
100 100 2 3 50 2 50
100 100 1 4 50
100 100 1 2 40
600 600 1 5 10
1000 10 1 1 50
0

样例输出

2.6667
1.5000
0.5333

题目来源

“IBM南邮杯”团队赛2009

题意不是很难,看到n=15我尝试了暴力、递归两种方法,T了之后乖乖地状压dp去了,用一个二进制数表示当前状态s,其中‘1’表示已经买过的pizza种类,然后依次去掉一个‘1’,得到s‘,由s‘可以转移得到s,dp[te]=mini(dp[te],dp[o]+p[k]*zhe[o][k] ); 其中p[k]代表第k种pizza的价格,zhe[o][k]代表的是第k种物品在状态s‘时所能获得的所有折扣,dp[te]表示状态s时最小的总价格。。。。然后,,,,就是一路优化常数的悲催经历了,,,感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,,

优化:

1.预处理了每个状态s时,第i种pizza所能得到的总折扣率。

2.去掉了位运算

3.预处理了每个状态中0的位置,0的总数

4.优化了dp顺序

5.还有各种稀奇古怪的,,,反正刚好不T了,我也就没管了,,,

附上题解:(来自陈老师)

Since each pizza can be bought at most once, we could solve the problem by enumerating all subsets of pizzas. However the order of buying the pizzas does matter, since coupons cannot be used retrospectively, and it is too slow to try all permutations of how to buy the pizzas.

The important observation is: given the subset of pizzas already bought, we do not care anymore about the order in which this subset of pizzas was bought. Therefore, we can use dynamic programming to solve this problem. We represent the subset of pizzas already bought by a bitmask with n bits, where bit i is set to 1 if and only if pizza i was already bought. The recurrence relation can be formulated as follows: minimum_price(mask) = minmask = submask + 2i minimum_price(submask) + price of pizza i where the price of pizza i is determined using discount coupons given for the pizzas bought before pizza i represented by the bitmask submask.

When calculating the minimum price for a subset of pizzas we only need to refer to bitmasks with a lower numeric value, therefore the recurrence relation can be calculated bottom up by enumerating all bitmasks with n bits from 0 to 2n-1. We need a table of size 2n, and each entry of the table can be calculated in O(n2) time, therefore the overall runtime is O(2nn2).

Judges‘ test data consists of 37 test cases; most of them are random-generated.

ps:最后三个是我的代码,前面ac的都是蔡神的

5954 njczy2010 G Accepted 12656 KB 921 ms GCC 2612 B 2014-11-27 22:08:52
5953 njczy2010 G Accepted 12656 KB 890 ms G++ 2823 B 2014-11-27 22:07:44
5951 njczy2010 G Accepted 12656 KB 921 ms GCC 2823 B 2014-11-27 22:05:53
5949 njczy2010 G Time Limit Exceed at Test 1     GCC 3044 B 2014-11-27 21:55:45
5948 njczy2010 G Time Limit Exceed at Test 1     GCC 3146 B 2014-11-27 21:53:51
5947 njczy2010 G Time Limit Exceed at Test 1     GCC 3150 B 2014-11-27 21:47:58
5946 njczy2010 G Time Limit Exceed at Test 1     GCC 2751 B 2014-11-27 21:13:15
5924 njczy2010 G Accepted 9312 KB 750 ms GCC 2223 B 2014-11-27 16:23:23
5918 njczy2010 G Time Limit Exceed at Test 1     GCC 3162 B 2014-11-27 16:14:19
5917 njczy2010 G Time Limit Exceed at Test 1     GCC 2967 B 2014-11-27 16:08:09
5916 njczy2010 G Compile Error     GCC 2965 B 2014-11-27 16:07:51
5915 njczy2010 G Time Limit Exceed at Test 1     GCC 2851 B 2014-11-27 16:05:25
5913 njczy2010 G Time Limit Exceed at Test 1     GCC 2806 B 2014-11-27 16:03:56
5911 njczy2010 G Accepted 9312 KB 859 ms G++ 2215 B 2014-11-27 15:53:04
5909 njczy2010 G Time Limit Exceed at Test 1     G++ 2996 B 2014-11-27 15:52:13
5908 njczy2010 G Time Limit Exceed at Test 1     G++ 2692 B 2014-11-27 15:26:46
5864 njczy2010 G Time Limit Exceed at Test 1     G++ 2482 B 2014-11-27 11:57:07
5863 njczy2010 G Time Limit Exceed at Test 1     G++ 2428 B 2014-11-27 11:55:09
5862 njczy2010 G Time Limit Exceed at Test 1     G++ 2416 B 2014-11-27 11:50:31
5861 njczy2010 G Time Limit Exceed at Test 1     G++ 2406 B 2014-11-27 11:44:55

这是水过去的代码:

  1 #include<stdio.h>
  2
  3 //#include<pair>
  4
  5 #define N 20
  6 #define M 1005
  7 #define mod 1000000007
  8 //#define p 10000007
  9 #define mod2 1000000000
 10 #define ll long long
 11 #define LL long long
 12 #define eps 1e-9
 13 #define maxi(a,b) (a)>(b)? (a) : (b)
 14 #define mini(a,b) (a)<(b)? (a) : (b)
 15
 16 int m;
 17 int x[N][N];
 18 double p[N],a[N],n[N],y[N][N];
 19 double zhe[ 32768 ][N];
 20 double ans;
 21 double dp[ 32768 ];
 22 double tta[ 32768 ];
 23 int tot;
 24 double zhezhe[N][N];
 25 int pos[ 32768 ];
 26 int son[ 32768 ];
 27 int pos2[ 32768 ][ 17 ];
 28 int cnt2[ 32768 ];
 29 int son2[ 32768 ][ 17 ];
 30 int h[16];
 31 char ss[17];
 32 int bit[32768][16];
 33
 34 void ini1()
 35 {
 36     int i,o,j,k,ch;
 37
 38     h[0]=1;
 39     for(i=1;i<16;i++)
 40         h[i]=2*h[i-1];
 41     for(o=0;o<32768;o++){
 42         k=o;
 43         j=0;
 44         ch=1;
 45         while(k > 0){
 46             bit[i][j] = k%2;
 47             k = k/2;
 48             j++;
 49         }
 50         for(j=0;j<15;j++)
 51         {
 52             if(bit[i][j]==0)
 53             {
 54                 pos2[o][ cnt2[o] ]=j;
 55                 cnt2[o]++;
 56             }
 57             else
 58             {
 59                 if(ch==1)
 60                 {
 61                     ch=0;
 62                     pos[o]=j;
 63                     son[o]= o - h[j];
 64                 }
 65             }
 66         }
 67     }
 68 }
 69
 70 void ini()
 71 {
 72     ans=1000000000;
 73     int i,j;
 74     int o;
 75     tot=h[m];
 76     for(i=1;i<=m;i++){
 77         for(j=1;j<=m;j++){
 78             zhezhe[i][j]=1.0;
 79         }
 80         scanf("%lf%lf%lf",&p[i],&a[i],&n[i]);
 81         for(j=1;j<=n[i];j++){
 82             scanf("%d%lf",&x[i][j],&y[i][j]);
 83             y[i][j]=(100.0-y[i][j])/100.0;
 84             zhezhe[i][ x[i][j] ]=y[i][j];
 85         }
 86     }
 87
 88     for(o=0;o<tot;o++){
 89         dp[o]=1000000000;
 90
 91     }
 92     for(j=1;j<=m;j++){
 93         zhe[0][j]=1.0;
 94     }
 95     tta[0]=0.0;
 96 }
 97
 98 void solve()
 99 {
100     int o,k,kk,j;
101     int te;
102     dp[0]=0;
103     for(o=0;o<tot;o++){
104         if(o>=1){
105             j=pos[o]+1;
106             te=son[o];
107             tta[o]=tta[te]+a[j];
108
109             for(kk=0;kk<cnt2[o];kk++){
110                 k=pos2[o][kk]+1;
111                 zhe[o][k]=zhe[te][k]*zhezhe[j][k];
112             }
113         }
114
115         for(kk=0;kk<cnt2[o];kk++){
116             k=pos2[o][kk]+1;
117             te=o+h[k-1];
118             dp[te]=mini(dp[te],dp[o]+p[k]*zhe[o][k] );
119         }
120     }
121 }
122
123 void out()
124 {
125     int o;
126     for(o=1;o<tot;o++){
127         //printf(" o=%d dp=%.4f\n",o,dp[o]);
128         ans=mini(ans,dp[o]/tta[o]);
129     }
130     printf("%.4f\n",ans);
131 }
132
133 int main()
134 {
135     ini1();
136    // freopen("data.in","r",stdin);
137     //freopen("data.out","w",stdout);
138     while(scanf("%d",&m)!=EOF)
139     {
140         if( m==0 ) break;
141
142         ini();
143         solve();
144         out();
145     }
146
147     return 0;
148 }
RunID User Problem Result Memory Time Language Length Submit Time
5860 njczy2010 G Accepted 9312 KB 734 ms GCC 2215 B 2014-11-27 11:44:14
5859 njczy2010 G Time Limit Exceed at Test 1     GCC 2215 B 2014-11-27 11:43:42
5858 njczy2010 G Time Limit Exceed at Test 1     G++ 2404 B 2014-11-27 11:36:29
5857 njczy2010 G Time Limit Exceed at Test 1     G++ 3036 B 2014-11-27 11:24:57
5856 njczy2010 G Time Limit Exceed at Test 1     G++ 3466 B 2014-11-27 11:13:39
5854 njczy2010 G Time Limit Exceed at Test 1     G++ 3413 B 2014-11-27 11:07:27
5849 njczy2010 G Time Limit Exceed at Test 1     G++ 3722 B 2014-11-27 10:23:56
5848 njczy2010 G Compile Error     G++ 3716 B 2014-11-27 10:23:19
5847 njczy2010 G Time Limit Exceed at Test 1     G++ 3330 B 2014-11-27 10:12:09
5846 njczy2010 G Time Limit Exceed at Test 1     G++ 3322 B 2014-11-27 10:09:51
5845 njczy2010 G Time Limit Exceed at Test 1     G++ 3323 B 2014-11-27 10:08:35
5844 njczy2010 G Time Limit Exceed at Test 1     G++ 3156 B 2014-11-27 10:05:04
5842 njczy2010 G Time Limit Exceed at Test 1     GCC 2916 B 2014-11-26 23:30:18
5841 njczy2010 G Time Limit Exceed at Test 1     G++ 2986 B 2014-11-26 23:23:18
5840 njczy2010 G Wrong Answer at Test 1     G++ 2986 B 2014-11-26 23:22:42
5839 njczy2010 G Wrong Answer at Test 1     G++ 2984 B 2014-11-26 23:19:33
5838 njczy2010 G Wrong Answer at Test 1     G++ 2982 B 2014-11-26 23:18:46
5837 njczy2010 G Time Limit Exceed at Test 1     G++ 2981 B 2014-11-26 23:07:33
5836 njczy2010 G Time Limit Exceed at Test 1     G++ 2715 B 2014-11-26 22:58:10
5830 njczy2010 G Time Limit Exceed at Test 1     G++ 2167 B 2014-11-26 22:28:24
时间: 2024-10-15 23:23:55

NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]的相关文章

NOJ 1116 哈罗哈的大披萨 【淡蓝】 状态压缩DP

哈罗哈的大披萨 [淡蓝] 时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte总提交 : 99            测试通过 : 14 比赛描述 热风哈罗哈(三牌楼)店正在搞活动:他们将提供一个大披萨给第一个告诉他们以下信息的人:一次购买任一种披萨,哪种单位面积的价格最低.问题初步想一想,好像是这么解决:"对于每个披萨计算平均价格,那么最小值就是答案了." 但是,这个问题不是这么简单,因为在热风哈罗哈店里:对某些披萨,是送打折优惠

解决MOFH免费空间cpanel面板大文件无法解压的情况

解决办法: 解压大文件,重新压缩为tar格式的压缩格式,这样可以更小,而且也可以在cpanel面板解压,记得使用filezilla软件上传文件,在cpanel的网页界面不要刷新,一刷新就不可以解压大文件tar格式了,会提示"Files which are too big can't be downloaded, uploaded, copied, moved, searched, zipped, unzipped, viewed or edited; they can only be renam

[转]浅析大数据量高并发的数据库优化

链接:http://www.uml.org.cn/sjjm/201308264.asp 高并发数据库可以同时处理海量信息,应用范围很广.今天我们将讨论的是大数据量高并发的数据库优化,希望对大家有所帮助. 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. 在一个系统分析.设计阶段,因为数据量较小,负荷较低.我们往往只注意到功能的实现,而很难注意到性

大页内存(HugePages)在通用程序优化中的应用

今天给大家介绍一种比较新奇的程序性能优化方法-大页内存(HugePages),简单来说就是通过增大操作系统页的大小来减小页表,从而避免快表缺失.这方面的资料比较贫乏,而且网上绝大多数资料都是介绍它在Oracle数据库中的应用,这会让人产生一种错觉:这种技术只能在Oracle数据库中应用.但其实,大页内存可以算是一种非常通用的优化技术,应用范围很广,针对不同的应用程序,最多可能会带来50%的性能提升,优化效果还是非常明显的.在本博客中,将通过一个具体的例子来介绍大页内存的使用方法. 在介绍之前需要

DevExpress ChartControl大数据加载时有哪些性能优化方法

DevExpress ChartControl加载大数据量数据时的性能优化方法有哪些? 关于图表优化,可从以下几个方面解决: 1.关闭不需要的可视化的元素(如LineMarkers, Labels等): Series.View.LineMarkerOptions.Visible =false. 2. 关闭图表的滚动与缩放功能,手动调整范围,这样将大大减少所需计算的个数. 3. 将 ChartControl.RefreshDataOnRepaint属性设为false 4. 将 ChartContr

湘大OJ1179Bird&#39;s Breakfast(dp)

题目描述 又是美好的一天,小鸟Jelly早早地起床,将要出门觅食.谁说没有天上掉馅饼的事,当Jelly出门时,惊奇地发现自己面前,N条悲催的小虫整齐地排成一排等待着Jelly享用.Jelly将这些虫标上序号1..N,当然,Jelly的警惕性还是很高的,他认为选择任意两条相邻的小虫i和i+1是危险的,但一条小虫都不吃显然是不现实的(p.s.因为会挨一天的饿-),吃多吃少无所谓.所以请你告诉Jelly它共有多少种选择方式. 输入 有多组输入数据, 每组输入数据一行,为N(1< N<=100000)

(转)大数据量高并发的数据库优化与sql优化

大数据量高并发的数据库优化 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. 在一个系统分析.设计阶段,因为数据量较小,负荷较低.我们往往只注意到功能的实现,而很难注意到性能的薄弱之处,等到系统投入实际运行一段时间后,才发现系统的性能在降低,这时再来考虑提高系统性能则要花费更多的人力物力,而整个系统也不可避免的形成了一个打补丁工程. 所以在考虑整

小a和uim之大逃离(luogu P1373 dp)

小a和uim之大逃离(luogu P1373 dp) 给你一个n*m的矩阵,其中元素的值在1~k内.限制只能往下和往右走,问从任意点出发,到任意点结束,且经过了偶数个元素的合法路径有多少个.在此题中,定义在一条路径中,第奇数个元素之和为X,第偶数个元素之和为Y.X+Y同模k+1的路径是合法路径.答案模1e9+7.n,m<=800,1<=k<=15. 状态是\(f[i][j][h][0/1]\),表示第i行第j列的元素,奇数元素和X-偶数元素和Y差为h,当前在路径中是第奇数个点或第偶数个点

[2018福大至诚软工助教]测试与优化小结

[2018福大至诚软工助教]测试与优化小结 一.得分 点击表头内相应项目可针对该项目进行排序. 学号1 学号2 单元测试10 结构优化10 性能调优10 奖励分0-3 总分30-33 6367 6445 10 10 10 2 32 6387 6354 8 7 3 0 18 6285 6314 0 0 0 0 0 6319 6321 3 0 0 0 3 6391 6380 0 0 0 1 1 6306 6308 7 3 0 0 10 6348 6338 4 0 0 0 4 6328 6331 0