鸡尾酒的寒假变得充实起来——因为又可以每天没日没夜地养孩子了.
游戏的每回合分为两个阶段,第一个阶段是学习阶段,可以花费一定的悟性学习技能.
有一条长度为的学习路径,只有当学习了路径上的第i个技能之后,才会在下一回合解锁第i+1个技能
(即每回合最多学习一个技能)
第个技能所需要花费的悟性为max(ki-A-B,ci).其中A,B为当前的智商值和情商值.
(初始状态为A=0,B=0.ki为第i个技能的最高花费,ci为第i个技能的最低花费)
第二阶段是安排活动阶段,可以选择一个已学的技能,并获得这个技能所能提供的智商值和情商值.
(如果当前什么技能都没有学,则跳过该阶段)
鸡尾酒想在Q回合后学完这条路径上所有N个技能,请你帮帮忙算一下悟性值的最小花费.
第一行输入两个正整数N,Q
接下来行描述学习路径上的N个技能,
每行包括4个数字,分别为ki,ci,ai,bi为该技能所能提供的智商值和情商值
其中:
1<=N<=Q<=15 0<=ai,bi<=1e9,0<=ki<ci<=1e9
输出一行一个整数代表在Q个回合后学完路径上的所有技能所需要的最小花费.
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=1e5+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll k[20],c[20],a[20],b[20];//n个阶段最高花费最低花费 情商智商
//状压枚举 回合数可以比掌握技能数多
int main()
{
ios::sync_with_stdio(false);
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
cin>>k[i]>>c[i]>>a[i]>>b[i];
}
ll minn=inf;//ci=1e9 n<=15 学n个 ll
//3e4状态 *20回合= 6e5
for(int i=0;i<(1<<q);i++)//000..00-15个1 q回合 2^q次方种状态
{//2^15=1024*32=3e4
ll ab=0,maxab=0,ans=0,cnt=0;
for(int j=0;j<q;j++)//判断每一个回合是否学技能 比如15个回合 最大移14位
{
if(i &(1<<j))//此回合学技能 判断此位是否为1 为1学
{
ans+=max(k[cnt+1]-ab,c[cnt+1]);//当前累积的a+b
if(maxab<a[cnt+1]+b[cnt+1])
maxab=a[cnt+1]+b[cnt+1];
ab+=maxab;
cnt++;//学了 到下次为1解锁下一阶段
}
else
{
ab+=maxab;
}
}
//求所有合法状态的最小花费
if(cnt!=n)//多了 少了
{
continue;
}
else
minn=min(ans,minn);//n<=q q回合一定能学会n个技能
}
cout<<minn<<endl;
return 0;
}
/*
3 5
10 0 3 3
20 5 1 2
50 10 100 100
*/
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define forn(i,n) for(int i=0;i<n;i++)
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int maxn=5005; //200堆
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
ll n,q;
ll a[25],b[25],k[25],c[25];
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i]>>k[i]>>c[i];
}
ll ab=0,maxab=0,ans=0,minn=inf,cnt=0;
for(ll i=0;i<(1<<q);i++){
ans=0,ab=0,maxab=0,cnt=0;//已掌握的最大情智商和
for(ll j=0;j<q;j++){
if(i & (1<<j)){ //这一回合第一阶段学技能解锁
ans+=max(k[cnt+1]-ab,c[cnt+1]);//c不变 让ab尽量大
// 新学的是否最高
if(maxab<a[cnt+1]+b[cnt+1]) //已掌握技能中情智商最大值
maxab=a[cnt+1]+b[cnt+1];
ab+=maxab;
cnt++; //掌握技能了
}
else{ //不解锁下一个技能跳过该阶段 光练提高智情商
ab+=maxab;//+已学技能中提高最快的 减少悟性花费
}
}
if(cnt==n)
minn=min(minn,ans);
else
continue;
}
cout<<minn<<endl;
return 0;
}