题意
有一天男神约了学姐姐去看电影,电影院有一个活动,给你一个10*10的矩阵,每一个格子上都有一个0-9的整数,表示一共十种优惠券中的一种。
观众从左上角的格子开始走,走到右下角。每走到一个有着a号优惠券的格子,都必须要玩一个a分钟的游戏来领取这张优惠券。
每次只能向右或向下走。当走到右下角的时候,如果集齐10种优惠券就可以半价看电影呢。
为了能在学姐姐面前展示自己的才智,男神准备用最少的时间领取全部的优惠券(他要省出最多的时间陪学姐姐)。聪明的你能告诉男神,他最少要花费的时间是多少?
题解
状压DP
#include<bits/stdc++.h>
using namespace std;
const int V=(1<<10)-1;
const int maxn=10;
const int inf=100000000;
int dp[V+5][maxn+5][maxn+5];
int mapx[maxn+5][maxn+5];
int main(void)
{
#ifdef ex
freopen ("in.txt","r",stdin);
#endif
for (int i=1;i<=maxn;++i)
{
for (int j=1;j<=maxn;++j)
{
scanf("%d",&mapx[i][j]);
}
}
for (int i=1;i<=maxn;++i)
{
for (int j=1;j<=maxn;++j)
{
for (int S=0;S<=V;++S)
{
dp[S][i][j]=inf;
}
}
}
dp[0|(1<<mapx[1][1])][1][1]=mapx[1][1];
for (int i=1;i<=maxn;++i)
{
for (int j=1;j<=maxn;++j)
{
if (i==1 && j==1) continue;
int &t=mapx[i][j];
for (int S=0;S<=V;++S)
{
if (S>=t)
{
if (i>1)
{
dp[S][i][j]=min(dp[S][i][j],dp[S&~(1<<t)][i-1][j]);
dp[S][i][j]=min(dp[S][i][j],dp[S][i-1][j]);
}
if (j>1)
{
dp[S][i][j]=min(dp[S][i][j],dp[S&~(1<<t)][i][j-1]);
dp[S][i][j]=min(dp[S][i][j],dp[S][i][j-1]);
}
dp[S][i][j]+=t;
}
}
}
}
printf("%d\n",dp[V][maxn][maxn]);
}