EC-FInal的题。。要是场上出了就好了。。。

题意:有N只蚂蚁玩饥饿游戏,在一个x轴上,第i只蚂蚁在坐标i上,重量为i,现在蚂蚁可以选择向左走或向右走,当两只蚂蚁相遇时大蚂蚁吃掉小蚂蚁,重量增加小蚂蚁的重量,如果重量相同,左边的蚂蚁吃掉右边的蚂蚁,给出N,K,问第K只蚂蚁最后留下的情况数。

数据范围: N<=10^6  K>=1 K<=N

解题:对于第N只蚂蚁,如果他想获胜,那么最后一个向左走的蚂蚁的前缀和必须小于其右边蚂蚁的后缀和,因为向左走的蚂蚁最终肯定会吃完(可能不是他吃完)左边直到1位置的所有蚂蚁然后向右走,此时这只向右走的蚂蚁的重量为1-最后一只向左走的蚂蚁的重量的和x,而他右边的蚂蚁向右走,那么最终必会被第N只蚂蚁吃掉,并且最后第N只蚂蚁的重量和为最后一只向左走的蚂蚁右边的蚂蚁的重量和y,此时两只蚂蚁相遇,如果第N只蚂蚁要获胜,那么x<y,所以只要找到这个位置len,那么情况数为2^(len+1),因为len+1~(n-1)的方向都确定了,剩下的随便选方向。

下面考虑对于N,K,可以发现(N,K))可以推到(N-1,K)的情况,即第N-1只蚂蚁向左拐的情况,可以发现此时因为第K只蚂蚁为获胜者,所以他最后必定向右走,重量为1-N-1只蚂蚁的重量和x,而右边的蚂蚁的重量和为第N只蚂蚁的重量y,那么只要x>y,第K只蚂蚁就会获胜,令dp[n-1]表示(N-1,K)的答案,那么(N,K)+=dp[n-1]/2 *2;/2表示第N-1只蚂蚁本来在长度为N-1时可以双向走,但长度为N时规定方向向左,但第N只蚂蚁可以双向走,所以再*2;

依此类推,只要后缀和小于前缀和,就可以加上情况数。

即dp[n]=dp[n-1]+dp[n-2]+...dp[w]  (令蚂蚁重量前缀和为a[i],则a[w]<a[n]-a[w] ,w为最小的满足情况的值,且w>=k;)

利用后缀和统计的方式,解法就是O(n)的啦。。

#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<string.h>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=2000000;
#define mod 1000000007
ll a[maxn];
ll dp[maxn];
ll to[maxn];
ll tot[maxn];
int bit[maxn];void init()//sum
{a[0]=0;for(int i=1;i<=1000000;i++)a[i]=a[i-1]+(ll)i;to[0]=1ll;for(int i=1;i<=1000005;i++)to[i]=to[i-1]*(ll)2,to[i]=to[i]%mod;bit[0]=0;for(int i=1;i<=1000005;i++){
//        cout<<i<<endl;int tmp=bit[i-1];ll tmp2=(ll)i*(i+1);while(2ll*tmp*(tmp+1)<tmp2) tmp++;bit[i]=tmp;}
}//
//ll get(int n,int k)//递归太多层爆了本地栈?
//{cout<<n<<" get "<<k<<endl;
//    ll ans=0;
//    ll sum=(ll)n;
//    for(int i=n-1;i>=k;i--)
//    {
//        if(dp[i]==0) get(i,k);
//        if(a[i]>=sum) ans+=dp[i],ans%=mod;
//        else break;
//        sum+=i;
//    }
//    return dp[n]=ans;
//}
//不用递归,统计前缀和ll get(int n,int k)
{tot[k]=dp[k];for(int i=k+1;i<=n;i++){int tmp=bit[i];
//        cout<<i<<" get "<<(tmp-1)<<endl;if(tmp-1>=k)dp[i]=((tot[i-1]-tot[tmp-1])%mod+mod)%mod;elsedp[i]=tot[i-1];tot[i]=(tot[i-1]+dp[i])%mod;}return dp[n];
}
int main()
{int cas;
//    freopen("write.txt","w",stdout);init();
//    for(int i=1;i<=15;i++)
//        cout<<i<<" "<<bit[i]<<endl;scanf("%d",&cas);int n,k;for(int ca=1;ca<=cas;ca++){scanf("%d%d",&n,&k);printf("Case #%d: ",ca);if(n==1 && k==1) {puts("2");continue;}ll sum=(ll)k;memset(dp,0,sizeof(dp));for(int i=k-1;i>=1;i--){if(sum>a[i]){dp[k]=to[i+1];break;}sum+=i;}
//        cout<<dp[k]<<endl;
//        cout<<dp[k]<<endl;if(n==k) printf("%lld\n",dp[k]);else printf("%lld\n",get(n,k));
//        cout<<dp[1000]<<endl;
//        cout<<dp[7]<<" "<<dp[8]<<endl;}
}

UVALIVE 7505 Hungry Game of Ants DP相关推荐

  1. 【UVALive 7505】Hungry Game of Ants(DP)

    [UVALive 7505]Hungry Game of Ants(DP) 题目大意: 一条链上n只蚂蚁,第i只蚂蚁的weight为i.每只蚂蚁会选择一个初始方向,向左或向右.两只蚂蚁相遇时,大体重的 ...

  2. UVALive 7143 Room Assignment(组合数学+DP)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  3. Regional 做题记录 (50/50)

    写在前面 博主深感自己太弱了QAQ 于是有了一个刷水的想法,Regional的题目还是有很多考查思维的题目,所以这次是乱做50道思考题,可能会顺带做一些水题,这些题的简要题解会写到这篇博文里面,希望能 ...

  4. DP UVALive 6506 Padovan Sequence

    题目传送门 /*题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[ ...

  5. uvaLive 4490 Help Bubu 帮助布布 等价转化+DP

    等价转换: 从有n本书的书堆里面抽取k本书,再插入书堆里面,计算书的杂乱度 等价于 向空的书架上按给出的顺序放上n本书,再从中抽取k本书,然后插入书堆里面,计算书的杂乱度 等价于 向空的书架上按给出的 ...

  6. UVALive 4043 Ants(最大权匹配)

    题目链接: UVALive 4043 Ants 题意: 给出平面上n个白点和n个黑点的点坐标,将这n个白点和n个黑点用n条不相交的线段连接,输出每个白点连接的黑点的编号. n<=100. 分析: ...

  7. UVALive 4126 Password Suspects(AC自动机+dp)

    题意就是长度为n的串,满足下列m个串是它的子串,问这个串有多少种,如果少于42种则字典序输出. dp[i][j][k]为,填充了i个字符,在ac自动机的j节点上,字串集合为k的方案数,填充i个字符可以 ...

  8. UVALive 3942 Remember the Word(字典树+DP)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  9. DP(优化) UVALive 6073 Math Magic

    /************************************************ * Author :Running_Time * Created Time :2015/10/28 ...

最新文章

  1. 用Async函数简化异步代码
  2. 利用OpenCV的级联分类器类CascadeClassifier和Haar特征实现人脸区域的检测
  3. VMware 11 安装Mac 10.9
  4. 【渝粤题库】广东开放大学 系统工程 形成性考核
  5. mysql复制的工作原理及主从复制的实现
  6. 1.Redis简介与基本命令
  7. Asp.net2.0里访问Web.config的Section的示例
  8. java中的DAO设计模式
  9. 2个版本并存的python使用新的版本安装django的方法
  10. zul组件、zhtml组件、native组件的区别
  11. WEB 渗透之文件类操作
  12. 单独使用Quartz 2.1.7 时Job属性Spring无法注入
  13. ztree 树形菜单结构转JSON
  14. 中鑫吉鼎|保本理财产品的优缺点分析对比
  15. 2021 互联网公司时薪排行榜出炉!微软、美团很强!
  16. php第三方阿里云接口
  17. 无线充电的四种基本补偿结构
  18. 深度学习中的规范化(BN、LN等四种规范化)
  19. TXT迷你小说阅读器
  20. Nervos 双周报第 8 期:用爱发电的 RustCon Asia

热门文章

  1. android 一起关闭_与Android一起成长
  2. Java 报表Apache POI API与实现数据行分组折叠
  3. Linux中lftp命令 – 优秀的命令行FTP客户端
  4. PHP数据类型与数组
  5. python解析word试卷_(完整word版)Python期末复习题(必考)
  6. 【数理知识】向量数乘,内积,外积,matlab代码实现
  7. 【leetcode】43.1~n整数中1出现的次数
  8. AIGC生产工艺流程之games生产流程
  9. 苹果绕过ID_iOS 14 出现严重BUG,可绕过 Apple ID 锁
  10. 选择广州Java培训 铸就不悔人生