Title Link: http://www.lightoj.com/volume_showproblem.php?problem=1127
Test instructions: There are n objects (n<30) and a container with a capacity of W, asking how many ways to place items without filling the container.
Idea: State compression + two points. Consider the first N/2 as a whole, and the rest as a whole. The 1<< (N/2) state represents the first half of the item usage, and then the total volume of each state is calculated. Sort. And for the back half. The answer is simply to enumerate half and then find the lower bound of the W difference in the other half.
Code:
#include <stdio.h>#include <ctime>#include <math.h>#include <limits.h>#include <complex>#include <string>#include <functional>#include <iterator>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <set>#include <map>#include <list>#include <bitset>#include <sstream>#include <iomanip>#include <fstream>#include <iostream>#include <ctime>#include <cmath>#include <cstring>#include <cstdio>#include <time.h>#include <ctype.h>#include <string.h>#include <assert.h>using namespace STD;intNLong LongWLong Longa[1000000];Long Longs1[1000000];Long Longs2[1000000];intMain () {intTscanf("%d", &t);intCases =1; while(t--) {memset(S1,0,sizeof(s1));memset(S2,0,sizeof(S2));memsetA0,sizeof(a));scanf("%d%lld", &n, &w); for(inti =0; I < n; i++)scanf("%lld", &a[i]);intT1 = n >>1;intt2 = n-t1;intR1 =1<< T1;intr2 =1<< T2; for(inti =0; I < R1; i++) for(intj =0; J < T1; J + +) {if(I & (1<< j)) S1[i] + + a[j]; } for(inti =0; i < R2; i++) for(intj =0; J < T2; J + +) {if(I & (1<< j)) S2[i] + + a[t1 + j]; } sort (s2, s2 + r2);Long LongAns =0; for(inti =0; I < R1; i++) {if(W-s1[i] >=0) ans + = upper_bound (s2, s2 + r2, w-s1[i])-S2; }printf("Case%d:%lld\n", cases++, ans); }return 0;}
Copyright NOTICE: Reprint please indicate the source.
Lightoj 1127-funny knapsack "two points"