Each place they visited will cost every person certain amount of money. And each person has a positive value for each place, representing his or her interest in this place. To make things more complicated, if two friends visited a place together, they will get a non negative bonus because they enjoyed each other’s companion. If more than two friends visited a place together, the total bonus will be the sum of each pair of friends’ bonuses.
Your task is to decide which people should take the tourism and when each of them should leave so that the sum of the interest plus the sum of the bonuses minus the total costs is the largest. If you can’t find a plan that have a result larger than 0, just tell them to STAY HOME.
A case starting with 0 0 indicates the end of input and you needn’t give an output.
2 1 10 15 5 0 5 5 0 3 2 30 50 24 48 40 70 35 20 0 4 1 4 0 5 1 5 0 2 2 100 100 50 50 50 50 0 20 20 0 0 0
5 41 STAY HOME
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=(1<<28);
int n,m;
int dp[12][1<<11];//dp[i][j]表示前i个地方,去的人的状态是j的最大兴趣值
int cost[12];
int interest[12][12];
int bonus[12][12];
int geti(int x,int state)//第x个地方给state状态的人的加入带来的效益
{
int cnt=0;
for(int i=0;i<n;i++)
{
if(state&(1<<i))
{
cnt-=cost[x];
cnt+=interest[i][x];
for(int j=i+1;j<n;j++)//important i+1 防止重复计算
{
if(state&(1<<j))
{
cnt+=bonus[i][j];
}
}
}
}
return cnt;
}
int main()
{
while(scanf("%d%d",&n,&m)==2&&n)
{
for(int i=0;i<m;i++)scanf("%d",&cost[i]);
for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&interest[i][j]);
for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&bonus[i][j]);
for(int i=0;i<(1<<n);i++)
{
dp[0][i]=geti(0,i);
}
for(int i=1;i<m;i++)
{
for(int j=0;j<(1<<n);j++)
{
int cnt=geti(i,j);//每两个朋友访问同一个地方,就要加上一次bonus
dp[i][j]=dp[i-1][j]+cnt;
for(int k=j+1;k<(1<<n);k++)
{
if((k&j)==j)//旅游过程中可以离开,所以i-1要比i的人多,且i的人i-1都有
{
dp[i][j]=max(dp[i][j],dp[i-1][k]+cnt);
}
}
}
}
int ans=0;
for(int i=0;i<(1<<n);i++) ans=max(ans,dp[m-1][i]);
if(ans) printf("%d\n",ans);
else printf("STAY HOME\n");
}
return 0;
}