男神的约会
Time Limit: 3000/1000MS (Java/Others)
Memory Limit: 65535/65535KB (Java/Others)
有一天男神约了学姐姐去看电影,电影院有一个活动,给你一个10*10的矩阵,每一个格子上都有一个0-9的整数,表示一共十种优惠券中的一种。
观众从左上角的格子开始走,走到右下角。每走到一个有着a号优惠券的格子,都必须要玩一个a分钟的游戏来领取这张优惠券。每次只能向右或向
下走。当走到右下角的时候,如果集齐10种优惠券就可以半价看电影呢。为了能在学姐姐面前展示自己的才智,男神准备用最少的时间领取全部的
优惠券(他要省出最多的时间陪学姐姐)。聪明的你能告诉男神,他最少要花费的时间是多少?
Input
输入包含10行,每行10个数字,以空格隔开,表示格子上的优惠券的种类。数据保证存在合法路径。
Output
输出男神走到右下角的最小时间花费。
用dp[i][j][k]表示当位于(i,j)时,收集情况为[k]这种情况所耗费的时间,因为只能向右或者向左走,所以只需将上面和左边的各1024个情况扫一遍,然后找出
存在的情况转移一下。
用t表示这一格的道具,那么这一格的状态用左边或者上面的格子或运算一下就可以了。
转移方程: dp[i][j][k|(1<<t)]=min(dp[i-1][j][k]+t,dp[i][j-1][k]+t)
最后再把dp[10][10][1023]输出来就可以了.
代码 :
//************************************************************************//
//*Author : Handsome How *//
//************************************************************************//
//#pragma comment(linker, "/STA CK:1024000000,1024000000")
#pragma warning(disable:4996)
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cassert>
#if defined(_MSC_VER) || __cplusplus > 199711L
#define aut(r,v) auto r = (v)
#else
#define aut(r,v) __typeof(v) r = (v)
#endif
#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
#define cl(a) memset((a),0,sizeof(a))
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sc(x) scanf("%d",&x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const int mod=1000000007;
const double pi=acos(-1);
inline void gn(long long&x){
int sg=1;char c;while(((c=getchar())<'0'||c>'9')&&c!='-');c=='-'?(sg=-1,x=0):(x=c-'0');
while((c=getchar())>='0'&&c<='9')x=x*10+c-'0';x*=sg;
}
inline void gn(int&x){long long t;gn(t);x=t;}
inline void gn(unsigned long long&x){long long t;gn(t);x=t;}
inline void gn(double&x){double t;scanf("%lf",&t);x=t;}
inline void gn(long double&x){double t;scanf("%lf",&t);x=t;}
//----------------------------------------------------------
int dp[11][11][1024];
int fig[11][11];
void solve(){
fur(i,1,10)fur(j,1,10){
int t = 1<<fig[i][j];
fur(k,0,1023)if(dp[i-1][j][k]!=inf)
if(dp[i-1][j][k]<1000)
dp[i][j][k|t]=min(dp[i][j][k|t],dp[i-1][j][k]+fig[i][j]);
fur(k,0,1023)
if(dp[i][j-1][k]<1000)
dp[i][j][k|t]=min(dp[i][j][k|t],dp[i][j-1][k]+fig[i][j]);
}
}
void init(){
memset(dp,0x3f,sizeof(dp));
int t = 1<<fig[1][1];
dp[1][1][1<<fig[1][1]] = fig[1][1];
}
int main()
{
fur(i,1,10)fur(j,1,10)gn(fig[i][j]);
init();
solve();
printf("%d\n",dp[10][10][1023]);
return 0;
}