给定一个初始状态无序的字符串(长度小于15),A、B两人从此串中依次取出一个字符,假设两人都足够理性,若取完后字符串严格递增有序(a[0]<a[1]<a[2]<...<a[n-1]),则此人获胜。
假设A先取,试判定A最终是胜还是负。
如:213,则A胜
222,则A败
2213,则A胜
假设AB都足够聪明,并都以获胜为目标。
思路:
1.在其中一个人获胜时,我们则要修改上一次另一个人的选择;
2.当某一个人穷尽所有想法都无法获胜,则他需要返回到他上一次的选择,采用另一种结果。
原理也就这么简单。
对于c++和java来说,可以使用map或者hash表记录出现的可能字符串,继而记录该字符串是否可以获胜,后面抽签所获得的字符串就可以引用之前的测试结果,从而加快效率。然后由递归,计算各种字符串组合是否可以满足严格递增有序,然后就可以判断A逐个抽出是否可以获胜了。
这里的record记录的是取出一个数字后剩余序列是否可以获胜。
#include <iostream>
#include <string>
#include <map>
using namespace std;
map<string, int> record;
int dp(string str){
if (record.find(str) != record.end())
{
return record[str];
}
int i;
for (i =1; i < str.size(); i++)
{
if (str[i-1] >= str[i])
{
break;
}
}
if (i == str.size())
{
record[str] = 0;
return 0;
}
for ( i= 0; i < str.size(); i++)
{
if (dp(str.substr(0,i) + str.substr(i+1)) == 0) {
break;
}
}
record[str] = (i != str.size()); //1:可以获胜
return record[str];
}
int main(){
string str;
cin >> str;
cout << dp(str) << endl;
system("pause");
return 0;
}
那么,c则没这些辅助,就得靠自己了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int level=0;
int pd(int who, int* data, int n){ //返回向上层数
int k, kk;
int *newdata;
int curwhook;
for(k=0; k<n; k++){
newdata = (int*)malloc(sizeof(int)*(n-1));
if(k==0)
memcpy(newdata, data+1, sizeof(int)*(n-1));
else if(k==n-1)
memcpy(newdata, data, sizeof(int)*(n-1));
else{
memcpy(newdata, data, sizeof(int)*k);
memcpy(newdata+k, data+k+1, sizeof(int)*(n-k-1));
}
for(kk=1; kk<n-1; kk++){ //判断剩余序列是否严格递增
if(*(newdata+kk)<=*(newdata+kk-1))
break;
}
if(kk==n-1){ //序列严格递增
//free(data); //-----------
free(newdata); //-----------
if(level==0){ //第0层,则可以确定必赢
printf("A win\n");
system("pause");
exit(0);
}
else{ //非第0层,返回上一层,让另一个人重新选
level--;
return 1; //返回上一个用户
}
}
else{ //并无严格递增
level++;
if(who==0){ //这次是A取的,下一次要B取
if(pd(1, newdata, n-1)==1){
free(newdata); //----------
continue;
}
else{ //-1
//free(data); //-----------
free(newdata); //-----------
level--; //------------
return 1;
}
}
else{
if(pd(0, newdata, n-1)==1){
free(newdata); //-----------
continue;
}
else{ //-1
//free(data); //-----------
free(newdata); //-----------
level--; //-------------
return 1;
}
}
}
}
if(k==n){ //穷尽了但找不到,返回同一个用户继续下一次循环
if(level==0)
printf("B win\n");
else{
//free(data); //-----------
//free(newdata); //-----------
level--;
if(level==0){
printf("A win\n");
system("pause");
exit(0);
}
return -1;
}
}
}
int main(void){
char s[20];
int slen, k, kk;
int *data;
int budayucnt;
if(gets(s)==NULL)
return 0;
slen = strlen(s);
data = (int*)malloc(sizeof(int)*slen);
for(k=0; k<slen; k++){
*(data+k) = s[k]-'0';
}
pd(0, data, slen);
system("pause");
return 0;
}