UVA 10404 Bachet's Game

来源:互联网 发布:平面图绘图软件 编辑:程序博客网 时间:2024/05/13 05:48

大意不再赘述。

思路:我思考了好久,最终还是没想出来,去网上搜了搜解题报告,发现大多是似是而非的观点,于是把自己的想法写出来。

我们把Stan取石子记为0,Ollie取记为1。以第一组测试数据为例: 20 3 1 3 8

如果Stan想赢,则20的标记应该是0,我们以f[20] = 0,表示Stan取的第20颗石子,依次类推。

那么20的前态:19 17 15,则三个数之间必须有一个f值为1才可以,因为只要f[19] || f[17] || f[15] = 1,那么f[20]就可以等于0,因为题目满足最优子结构,而且Ollie取过其中的一个,Stan一定会取第20个石子,那么Stan wins,反之,Ollie wins,其他的子状态依次类推,最后我们最后只要判断f[n]是否为0即可。

另外:把a数组赋值为1,题目如果是Ollie先取呢?由于两者的状态相同,我们把输出改一下即可。

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>using namespace std;int stone[11];int a[1000100];int n, m;char sw[20] = "Stan wins\n";char ow[20] = "Ollie wins\n";void init(){memset(a, 1, sizeof(a));}void dp(){for(int i = 0; i <= n; i++){for(int j = 1; j <= m; j++){if(a[i]){a[i+stone[j]] = 0;}}}if(a[n] == 0) printf("%s", sw);else printf("%s", ow);}void read_case(){init();scanf("%d", &m);for(int i = 1; i <= m; i++){scanf("%d", &stone[i]);}}void solve(){read_case();dp();}int main(){while(~scanf("%d", &n)){solve();}return 0;}