题目
好自闭啊,5KB的背包鬼知道我经历了什么
设 L = 40 L = 40 L=40
如果没有物品之间的限制,对于一组可以 O ( n log n ) O(n\log n) O(nlogn)贪心求出只有 w = 1 , 2 w=1,2 w=1,2的答案再和 w = 3 w = 3 w=3的合并,注意到我们只需要 m L mL mL个状态,对于多组可以直接 O ( L 2 ) O(L^2) O(L2)合并,所以这部分复杂度是 O ( m L 2 ) O(mL^2) O(mL2)的。(分析其实没有看上去那么简单。)
听说w \leq 5都可以闵科夫斯基和的
有物品的限制就枚举状态后继续做之前的工作,注意能预处理的一定要预处理,然后其实就一点都不卡常。
A C C o d e \mathcal AC \ Code AC Code
#include
#define maxm 50055
#define maxn 500055
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
#define LL long long
#define pb push_back
#define pii pair
#define vc vector
#define vi vc
#define mp make_pair
#define Ct const
#define db double
using namespace std;
namespace IO{
char cb[1<<16] , *cs=cb,*ct=cb;
char getc(){ return cs == ct && (ct = (cs = cb) + fread(cb,1,1<<16,stdin),cs == ct) ? 0 : *cs++; }
template<class T>void read(T &res){
char ch;bool f=0;
for(;!isdigit(ch=getc());) if(ch=='-') f = 1;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
(f) && (res = -res);
}
};
using IO :: getc;
using IO :: read;
int m,T,p,cus[maxm],tim;
int n[maxm],s[maxm];
int *w[maxm] , *c[maxm];
int dat[200][6];
int id[maxm],hdq[maxm],mus[maxm],*hdl[maxm];
int f[55],g[55],G[55],d[maxm],dp[maxn * 3],dp2[maxn * 3];
int main(){freopen("courses.in","r",stdin);
freopen("courses.out","w",stdout);
read(m) , read(T);
vector<pii >pts;
rep(i,1,m){
read(n[i]) , read(s[i]);T -= s[i];
c[i] = new int [n[i] + 5];
w[i] = new int [n[i] + 5];
hdl[i] = new int [n[i] + 5];
rep(j,1,n[i])
read(w[i][j]) , read(c[i][j]);
}
read(p);
int il = 1 , ir = m;
rep(i,0,p-1){
rep(j,0,4) read(dat[i][j]);
hdq[dat[i][1]] = hdq[dat[i][3]] = 1;
hdl[dat[i][1]][dat[i][2]] =
hdl[dat[i][3]][dat[i][4]] = 1;
pts.push_back(mp(dat[i][1] , dat[i][2]));
pts.push_back(mp(dat[i][3] , dat[i][4]));
if(dat[i][0] != 3) read(dat[i][5]);
}
sort(pts.begin(),pts.end());
pts.resize(unique(pts.begin(),pts.end())-pts.begin());
rep(i,1,m) if(hdq[i]) id[ir--] = i;
else id[il++] = i;
memset(f,0x3f,sizeof f);
f[0] = 0;
int sm = 0;
rep(i,1,ir){
int u = id[i];
vector<int>s[4];
rep(j,1,n[u]) s[w[u][j]].push_back(c[u][j]);
sort(s[1].begin(),s[1].end());
sort(s[2].begin(),s[2].end());
sort(s[3].begin(),s[3].end());
rep(i,0,::s[u] + 45) dp[i] = 0x3f3f3f3f;
dp[0] = 0;
for(int i=2,a=0,b=0;a+1 < s[1].size() || b < s[2].size();i+=2){
if(b >= s[2].size() || (a+1 < s[1].size() && s[1][a] + s[1][a+1] < s[2][b]))
dp[i] = dp[i-2] + s[1][a] + s[1][a+1] , a += 2;
else
dp[i] = dp[i-2] + s[2][b++];
}
if(!s[1].empty()){
dp[1] = s[1][0];
for(int i=3,a=1,b=0;a+1 < s[1].size() || b < s[2].size();i+=2){
if(b >= s[2].size() || (a+1 < s[1].size() && s[1][a] + s[1][a+1] < s[2][b]))
dp[i] = dp[i-2] + s[1][a] + s[1][a+1] , a += 2;
else
dp[i] = dp[i-2] + s[2][b++];
}
}
bool flg = 0;
static int tf[55];
memset(tf,0x3f,sizeof tf);
rep(j,0,45){
int a = dp[j + ::s[u]] , b= 0 ;
for(int k=0;k<=s[3].size() && 3 * k <= j + ::s[u];k++){
a = min(a , dp[j + ::s[u] - 3 * k] + b);
if(k < s[3].size())b += s[3][k];
}
per(k,45,0)
tf[min(k+j,45)] = min(tf[min(k+j,45)] , f[k] + a);
}
memcpy(f,tf,sizeof f);
}
memset(G,0x3f,sizeof G);
static int dp[13][maxn],pg[13][200];
vector<int>s[13][4];
rep(i,il,m){
int u = id[i] , p = i - il;
rep(j,1,n[u]) if(!hdl[u][j]) s[p][w[u][j]].push_back(c[u][j]);
sort(s[p][1].begin(),s[p][1].end());
sort(s[p][2].begin(),s[p][2].end());
sort(s[p][3].begin(),s[p][3].end());
rep(i,0,::s[u] + 90) dp[p][i] = 0x3f3f3f3f;
dp[p][0] = 0;
for(int i=2,a=0,b=0;a+1 < s[p][1].size() || b < s[p][2].size();i+=2){
if(b >= s[p][2].size() || (a+1 < s[p][1].size() && s[p][1][a] + s[p][1][a+1] < s[p][2][b]))
dp[p][i] = dp[p][i-2] + s[p][1][a] + s[p][1][a+1] , a += 2;
else
dp[p][i] = dp[p][i-2] + s[p][2][b++];
}
if(!s[p][1].empty()){
dp[p][1] = s[p][1][0];
for(int i=3,a=1,b=0;a+1 < s[p][1].size() || b < s[p][2].size();i+=2){
if(b >= s[p][2].size() || (a+1 < s[p][1].size() && s[p][1][a] + s[p][1][a+1] < s[p][2][b]))
dp[p][i] = dp[p][i-2] + s[p][1][a] + s[p][1][a+1] , a += 2;
else
dp[p][i] = dp[p][i-2] + s[p][2][b++];
}
}
memset(pg[p],0x3f,sizeof pg[p]);
rep(j,max(-::s[u],-36),45){
int a = dp[p][j + ::s[u]] , b = 0;
for(int k=0;k<=s[p][3].size() && 3 * k <= j + ::s[u];k++){
a = min(a , dp[p][j + ::s[u] - 3 * k] + b);
if(k < s[p][3].size()) b += s[p][3][k];
}
pg[p][j + 36] = a;
}
}
rep(sta,0,(1<<pts.size())-1){
bool flg = 0;
memset(g,0x3f,sizeof g);
g[0] = 0;
rep(i,il,m) d[id[i]] = 0;
rep(i,0,p-1){
int u = lower_bound(pts.begin() , pts.end() , mp(dat[i][1] , dat[i][2])) - pts.begin() ,
v = lower_bound(pts.begin() , pts.end() , mp(dat[i][3] , dat[i][4])) - pts.begin();
if((sta >> u & 1) && (sta >> v & 1)){
if(dat[i][0] == 3){ flg = 1; break;}
if(dat[i][0] == 1) g[0] -= dat[i][5];
if(dat[i][0] == 2) g[0] += dat[i][5];
}
}
if(flg) continue;
rep(i,0,pts.size() - 1) if(sta >> i & 1)
d[pts[i].first] += w[pts[i].first][pts[i].second] ,
g[0] += c[pts[i].first][pts[i].second];
rep(i,il,m){
int u = id[i] , p = i - il;
static int tg[55];
memset(tg,0x3f,sizeof tg);
rep(j,max(-d[u],-::s[u]),45){
per(k,45,0)
tg[min(k+j+d[u],45)] = min(tg[min(k+j+d[u],45)] , g[k] + pg[p][j + 36]);
}
memcpy(g,tg,sizeof g);
}
rep(i,0,45) G[i] = min(G[i] , g[i]);
}
int ans = 0x3f3f3f3f;
rep(i,0,45) rep(j,0,45)
if(i + j >= T)
ans = min(ans , f[i] + G[j]);
if(ans >= 0x3f3f3f3f) ans = -1;
printf("%d\n",ans);
}