有一个色子,每个面上有一个数字,
对面是
,我们可以把色子旋转
度,然后把顶面数字加入得分,求最少几步刚刚达到
分。若无解,输出-1
。
很明显的一道 题,但是也稍需思考。
我们很容易想到用 表示分数刚刚达到 时的步数,答案很好表示,就是 。但是,我们发现,这样做不好转移。因为转移与顶面的数字相关。
本着 这样的思想,所以我们修改我们的定义,即 表示刚刚达到 分且顶面为 时的答案。答案其实也很好表示,即:
转移的时候,因为有了 这一维,转移变得和方便,即:
const int inf=0x3f3f3f;
int f[10100][8],n,test_number;
inline void updata(int x,int v){
for(int i=1;i<=6;i++)
if (v!=i&&v+i!=7)
f[x+i][i]=min(f[x+i][i],f[x][v]+1);
}//转移
inline void dp_init(int n){
for(int i=0;i<=n;i++)
for(int j=1;j<=6;j++)
f[i][j]=inf;
f[0][1]=0;//初始化,注意初始1朝上
for(int i=0;i<=n;i++)
for(int j=1;j<=6;j++)
updata(i,j);
}//提前计算出答案
inline int answer(int n){
register int result=inf;
for(int i=1;i<=6;i++)
result=min(result,f[n][i]);
return result==inf?-1:result;
}//计算答案
int main(){
dp_init(10010);
scanf("%d",&test_number);
while (test_number--){
scanf("%d",&n);
printf("%d\n",answer(n));
}
return 0;
}
**************************
状态:Accepted
得分:100分
备注:没写头文件
**************************