现在的数据应该没错,我的算法很复杂(指可能是WA)
代码如下
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,c,ans,ans1,iu,ans2;
struct edge{
int bian,happy,use,now,nowh;
};
const int p=1e4+10;
edge g[p];
int v[p];
void work(int cur,int x,int happy)
{
if(cur>n-1)
{
return;
}
for(int i=1;i<=m;i++)
{
if(i==x)
{
g[x].now*=1.2;
g[x].nowh*=0.9;
if(cur+g[i].now<=n-1)
{
work(cur+g[i].now,i,happy+g[i].nowh);
}
g[x].now=g[x].use;
g[x].nowh=g[x].happy;
continue;
}
if(cur+g[i].now<=n-1)
{
int a=g[x].now;
int b=g[x].nowh;
g[x].now=g[x].use;
g[x].nowh=g[x].happy;
work(cur+g[i].now,i,happy+g[i].nowh);
g[x].now=a;
g[x].nowh=b;
}
}
if(happy>ans)
{
ans=max(ans,happy);
ans1=cur;
}
}
bool work1(int cur,int x,int happy)
{
if(happy==ans)
{
return 1;
}
for(int i=1;i<=m;i++)
{
if(i==x)
{
g[x].now*=1.2;
g[x].nowh*=0.9;
if(cur+g[i].now<=n-1)
{
v[i]++;
work1(cur+g[i].now,i,happy+g[i].nowh);
v[i]--;
}
g[x].now=g[x].use;
g[x].nowh=g[x].happy;
continue;
}
if(cur+g[i].now<=n-1)
{
v[i]++;
work1(cur+g[i].now,i,happy+g[i].nowh);
v[i]--;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
g[i].bian=a;
g[i].happy=b;
g[i].use=c;
g[i].now=c;
g[i].nowh=b;
}
for(int i=1;i<=m;i++)
{
if(g[i].now<=n-1)
{
v[i]++;
work(g[i].now,i,g[i].nowh);
v[i]--;
}
}
for(int i=1;i<=m;i++)
{
if(g[i].now<=n-1)
{
v[i]++;
if(work1(g[i].now,i,g[i].nowh))
{
break;
}
v[i]--;
}
}
for(int i=1;i<=m;i++)
{
int t=iu;
iu=max(iu,v[i]);
if(t!=iu)
{
ans2=i;
}
}
cout<<ans<<" "<<ans2<<" "<<ans1;
return 0;
}
暴力万岁!
因为涉及到重复选取,第一次选取是很正常的初始数据,第二次会叠加一层buff,第三次会叠加两层的buff,以此类推,并要求输出活动最多的编号,消耗的机会值。
题目中有个小坑,提到了 机会不能用完 的概念,其实也好解决,让输入的机会值直接减去一个一就可以了,让最大可用机会就是n-1,虽然可能用不完,但是不会爆掉。
首先读入编号等东西,让每个值都运行一次work,求出最大的快乐值happy,x代表上一次的选择(当前层数的选择),cur代表消耗的机会。
用now来代表现在的消耗值,nowh代表现在这个机会活动的快乐值。因为题中“强制类型转换int”就不需要开double来计算,每一次让所有的活动都进行递归if(x==i)当中还原now,nowh是在于选完之后要及时还原,不影响没选的时候的情况,如果选择的不是上一次连续做过的活动,那么它的值应该回归初始值,让now等于use,nowh等于happy
计算出最大的快乐ans,消耗ans1之后,因为我是蒟蒻,所以又打了一个work2,求出当时选择的路程,定一个数组v,让每一个i去v[i]++,并及时还原,求到当前happy等于ans的时候,就说明已经求到了之前work求出的最大快乐。(数据很弱,所以还在时间范围内,并且不存在有两种快乐值相等的情况)
并且求出来之后返回一个1,立即停止主函数中的遍历,因为此时v[i]--的话会导致错误,这个时候的i是要累加的,不可以减去。
最后遍历一遍v,求出数值最大的编号,cout这三个数值,结束。