设为首页 加入收藏

TOP

poj 1143 number game
2015-11-21 01:23:30 来源: 作者: 【 】 浏览:3
Tags:poj 1143 number game

题目比较长,题意不大好理解

现在把题意抽象一下,大概是以下意思:

1.给2~20的数字中的几个数组成数组a,其中是你可以选择的数字;

2.选择的规则如下:

(1).如果选择了某个数字x,则数组a中是其倍数的数字将被划去;

(2).假如数字n在数组a中,若n-x 的值并不在数组a中,则划去n;

3.当没有数字可以选取时,则此player失败;

4.让你找出先选的player选择哪个数字可以胜利。若没有选择输出“(所给的一句话)”

1.本题说是动态规划,但是在我看来,这道题 没有 状态转移方程,也没有 明显的 状态 需要来表示。状态转移应该就是代码中DP[state]是依赖于上一层的DP[state],这叫状态转移吗?如果算的话应该是最直白的状态转移了,因为没得选择只有一个依赖状态。

2.但是,我觉得这道题目确是实实在在地应用到了 记忆化搜索 的思想。因为当前状态DP[state]的计算需要依赖的上一层状态DP[state]在用到时是没有得出的,是在用到时往下搜索得到的。这里一旦搜过,就用状态DP[state]记录下了该状态下做选择的player能不能胜利(只用0和1来表示)。

3.其实在我看来,这道题目的最大亮点,应该是在上面DP[state]中所提到的这个state ~。这是一种用二进制存储的状态。因为数据范围只到20,而二进制状态存储起码对于31以及以下的数字还是可以存的。而且状态表示起来简单干净,转移起来干脆不拖泥带水。通过这道题很好地学习了二进制状态存取的方法以及位运算的知识。收益很多。

4.代码会好好加注释:

#include
  
   
#include
   
     #include
    
      using namespace std; const int maxn = (1<<21) + 10; int n; int a[22],ans[21]; int DP[maxn],vis[maxn]; bool judge(int i,int j,int st){ return ((((1<<(a[j]-a[i]))&(~st))&&(a[j]-a[i] != 1))||(a[j]%a[i] == 0)); } int dp(int k,int state){ if(vis[state]) return DP[state]; vis[state] = 1; if(state == 0) return 0;///没有元素可以选择了,说明本次选择失败返回0; if(k == 1) return DP[state] = 1;///只有一个元素可以选择说明成功,返回1; for(int i=0;i
     
      

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU4144:Bacon's Cipher 下一篇POJ 1696 Space Ant 计算几何 叉..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: