您的位置:首页 > 其它

UVA 1452 DP+Joseph变形

2013-09-26 12:50 197 查看
汝神白胖书第八题dp基础题

好吧╮(╯▽╰)╭我是没思路的(菜)(C++课后习题用的是很二的暴搜),在网上看到这个方法后自己直接拍了

居然交了4发才过(菜)

现在我自己来总结一下Joseph问题的这个解法

约瑟夫变形

n个人围成一圈,从第一个开始每次选出第k个将其移出

求最后第1,2,3个被移出的人开始的位置

比如

n = 5

1,2,3,4,5 k = 2

第一次 2  剩余的 3,4,5,1(将剩余的从移去的数的后一个数开始列成一行)

第二次 4  剩余的 5,1,3

第三次 1  剩余的 3,5

第四次 5  剩余的 3

第五次 3

记位置从0开始

我们可以看到

第四次的3 在第三次的位置为 (0 + 2) % 2 = 0

第三次的3 在第二次的位置为 (0 + 2) % 3 = 2

第二次的3 在第一次的位置为 (2 + 2) % 4 = 0

我们可以得到

第n次移除动作后, 剩余元素为tn,某元素a在该列中的位置为i

则在第n - 1次移除动作后,该元素的位置为 (i + k) % (tn + 1)

DP方程为 i = (i + k) % (tn + 1),当i到n时就是所求得的解

用这种方法可以算出所有第i个被移去的元素的开始位置:我们可以用ans[i]来记录

时间复杂度大概是O(n ^ 2)

#include <cstdio>
int main()
{
int T, n, k, lst1, lst2, lst3;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &k); lst1 = 0;
for(int i = 2; i <= n; i++)
{
lst1 = (lst1 + k) % i;
if(i == 2) lst2 = !lst1;
else{
lst2 = (lst2 + k) % i;
if(i == 3) lst3 = 3 - lst1 - lst2;
else lst3 = (lst3 + k) % i;
}
}
printf("%d %d %d\n", lst3 + 1, lst2 + 1, lst1 + 1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: