男神的约会
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
有一天男神约了学姐姐去看电影,电影院有一个活动,给你一个10*10的矩阵,每一个格子上都有一个0-9的整数,表示一共十种优惠券中的一种。
观众从左上角的格子开始走,走到右下角。每走到一个有着a号优惠券的格子,都必须要玩一个a分钟的游戏来领取这张优惠券。
每次只能向右或向下走。当走到右下角的时候,如果集齐10种优惠券就可以半价看电影呢。
为了能在学姐姐面前展示自己的才智,男神准备用最少的时间领取全部的优惠券(他要省出最多的时间陪学姐姐)。聪明的你能告诉男神,他最少要花费的时间是多少?
Input
输入包含10行,每行10个数字,以空格隔开,表示格子上的优惠券的种类。数据保证存在合法路径。
Output
输出男神走到右下角的最小时间花费。
Sample input and output
Sample Input | Sample Output |
---|---|
0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 0 2 1 1 1 1 1 1 1 1 0 3 1 1 1 1 1 1 1 1 0 4 1 1 1 1 1 1 1 1 0 5 1 1 1 1 1 1 1 1 0 6 1 1 1 1 1 1 1 1 0 7 1 1 1 1 1 1 1 1 0 8 1 1 1 1 1 1 1 1 0 9 1 1 1 1 1 1 1 1 5 | 50 |
Source
2015 UESTC Training for Dynamic Programming
用二进制的位数记录当前第i号钥匙是否存在
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<vector>
using namespace std;
int map[11][11];
int dp[15][15][2048];
int main()
{
int i,j,k,n,m;
for(i=1;i<=10;++i){
for(j=1;j<=10;++j){
scanf("%d",&map[i][j]);
}
}
memset(dp,0x3f,sizeof(dp));
dp[1][1][1<<map[1][1]]=map[1][1];
for(i=1;i<=10;++i){
for(j=1;j<=10;++j){
if(i==1&&j==1)continue;
for(k=0;k<=1023;++k){
dp[i][j][k|(1<<map[i][j])]=min(dp[i][j][k],min(dp[i-1][j][k],dp[i][j-1][k])+map[i][j]);
}
}
}
printf("%d\n",dp[10][10][1023]);
return 0;
}