# Ingress

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 102400/65535 K (Java/Others)
Total Submission(s): 440    Accepted Submission(s): 205

Problem Description
Brickgao, who profited from your accurate calculating last year, made a great deal of money by moving bricks. Now he became gay shy fool'' again and recently he bought an iphone and was deeply addicted into a cellphone game called Ingress. Now he is faced with a problem so he turns to you for help again. We make some slight modifications based on the original rules, so please draw attention to the details below.

There are N portals (indexed from 1 to N) around Brickgao's home, and he can get some substances called XM by hacking the portals. It's known that for each portal i, he can get Ai XM during the first hack, and after each hack, the amount of XM he will get during the next hack will decrease by Bi. If the amount of XM he can get is less than or equal to zero, Brickgao can't get XM from that portal anymore. For the i-th portal, if Ai=10,Bi=2 and he hacks 3 times, he will get 10, 8, 6 XM during each hack.

There are M bidirectional roads between some pairs of portals and between Brickgao's home and some portals. Now he is eager to start his Ingress journey from home and finally return home, but due to the extremely hot weather, Brickgao will feel sick when you hack more than K times or the distance he covers is more than L. So how much XM he can get at most during this journey?

Input
The first line contains a single integer T(T20), indicating the number of test cases.

The first line of each case are four integers N(1N16),M(0MN(N+1)2),K(1K50) and L(2L2000).
The second line of each case contains N non-negative integers where the i-th denotes Ai(Ai500).
The third line of each case contains N non-negative integers where the i-th denotes Bi(Bi50).
Each of next M line contains 3 non-negative integers u,v(0u,vn) and c(0c1000) , denotes that there is a road with the length of c between the u-th and the v-th portal. If u or v equals to 0, it means Brickgao's home.

Output
For each test case, output the case number first, then the amount of maximum XM Brickgao can get.

Sample Input
2 1 1 3 2 5 3 0 1 1 3 6 3 5 10 7 5 2 3 1 0 1 3 0 2 1 0 3 1 1 2 2 2 3 3 1 3 4

Sample Output
Case 1: 7 Case 2: 16

Source

【题意】

【分析】

obvious，主人公走到某个点，一定会取数取的尽量多，并且不再回来（回来的话，还不如上次在这的时候取着。）。当然他也可以路过某个点而不取。

dis[i][j]表示点i到j的最短路（floyd可求）

【代码】

#include<bits/stdc++.h>
#define rep(i,s,t) for(int i=s;i<=t;i++)
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int N=1e6+5;

int a[20],b[20];
int dis[20][20];
int dp[1<<17][20];
typedef pair<int,int> PII;
void floyd(int n)
{
for(int k=0;k<=n;k++)
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
}

int main()
{
int cas=0,T,n,m,k,L;
int u,v,w;
cin>>T;
while(T--)
{
cin>>n>>m>>k>>L;

for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
memset(dis,0x3f,sizeof(dis));
memset(dp,0x3f,sizeof(dp));
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
dis[u][v]=dis[v][u]=min(dis[u][v],w);
}
floyd(n);

dp[1][0]=0;
for(int i=0;i<(1<<(n+1));i++) ///已经到过的点
{
for(int j=0;j<=n;j++)if(i&(1<<j)) ///当前所在的点
{
for(int t=0;t<=n;t++)if((i&(1<<t))==0) ///可以去的点
{
dp[i|(1<<t)][t]=min(dp[i|(1<<t)][t],dp[i][j]+dis[j][t]); ///j->t
}
}
}
int ans=0;
for(int i=0;i<(1<<(n+1));i++) ///状态
{
int cango=0;
for(int j=0;j<=n;j++)
{
if((i&(1<<j))&&dp[i][j]+dis[j][0]<=L) ///i状态包含点j && 距离能回到0
cango=1;
}
if(!cango)continue; ///len too far
int res=0;
priority_queue<PII>q;
for(int t=0;t<=n;t++)if(i&(1<<t))
{
q.push(PII(a[t],b[t]));
}
for(int t=0;t<k&&!q.empty();t++) ///最多选k次
{
PII u=q.top(); q.pop();
res+=u.first;
u.first-=u.second;
q.push(u);
}
ans=max(ans,res);
}
printf("Case %d: %d\n",++cas,ans);
}
return 0;
}


• 评论

• 下一篇
• 上一篇