11月02日解题报告

来源:互联网 发布:软件成本估算专家 编辑:程序博客网 时间:2024/05/18 20:11

考试心得

首先吐槽一下题目deep dark fantasy??一看就不是什么正经题目,不过难度倒是比较好的,就不管那么多了,emmmm,做题的一个总的想法是还是要细心,感觉有时候想到了正解,但没想全也是A不了的,就像第一题,明明已经发现了正解,结果少考虑了条件,结果只有80分,还是有些不爽的,然后就是还是得多接触一些新题型吧,当然这个就需要做更多的题目才是,而且要记得及时总结,不然做了和没做一样;

第一题

题面
失败的燃烧军团想要逃回深渊,Khadgar 想要追击它们。
然而进入深渊的传送门只有一座,燃烧军团和 Khadgar 各有一些法力水晶,由 Khadgar 先手,双方每次可以作出如下选择:
• 使用一个法力水晶,使得传送门的法力等级增加一。
• 不用法力水晶,让对方增加等于传送门法力等级的深度,然后将传送门的法力值清零。特别地,若法力水晶数不为零且传送门法力等级为零则不能进行这样的操作。
双方都会采取最优策略使自己的最终深度与对手深度的差最大(初始时深度均为零)。
现在多次给定双方起始的法力水晶数量 A, B,求 Khadgar 与燃烧军团的的最终深度差。
Input Format:
T
A 1 B 1
A 2 B 2
···
A T B T
Output Format:
输出 T 行 T 个整数,表示 Khadgar 与燃烧军团的的深度差。
Sample Input:
2
0 1
4 1
Sample Output:
-1
1
AC思路
因为之前做过一道类似题面的dp题,所以一看就方了,dp?博弈轮?然后自己写了几组数据手推了一下,发现其实不是那么回事,因为如果后手在自身不为0的情况下,如果不把先手榨的小于等于1,那么先手就可以翻盘为后手,所以策略就出来了,然后判断一下两边是否为0即可;
代码

#include<iostream>#include<cstdio>using namespace std;int t;int main(){    //freopen("deep.in","r",stdin);    //freopen("deep.out","w",stdout);    scanf("%d",&t);    for(int i=1;i<=t;i++)    {        int a,b;        scanf("%d%d",&a,&b);        if(a==0||b==0)        cout<<a-b<<endl;        else         cout<<a-b-2<<endl;    }}

第二题

题面
Lich King 希望收集邪恶的黑暗力量,并依靠它称霸世界。
世间的黑暗力量被描述成一个长度为 N 的非负整数序列 {A i },每次它可以选择这个序列中的两个相邻的正整数,让他们的值同时减一并获得一点邪恶力量,直到不存在满足条件的数。
然而你不希望他能够得逞,所以你会使得他收集的能量尽可能少。
Input Format:
N
A 1 A 2 · · · A N
Output Format:
输出一行一个整数,表示答案。
Sample Input:
10
2 0 1 2 0 0 0 0 0 0
Sample Output:
1
AC思路
这道题我贪心只贪了30分,策略上有问题(其实是思维上的问题),然后发现了一位大佬的题解,感觉瞬解%%%;
大佬的思路:
我们设f[i]表示前i-1位全部合法,第i位减为0的最小代价,那么显然,我们可以从f[i-1]转移过来,那么f[i]=f[i-1]+a[i],这是一种。
第二个也比较容易想到,从f[i-2]转移过来,那第i-1位可能为0可能不为0,所以f[i]=f[i-2]+a[i]
第三个就是从f[i-3]转移过来,因为它是两个数一起减的,所以我们取a[i-1]和a[i]的最大值,f[i]=f[i-3]+max(a[i-1],a[i])
最后取一下三个式子的最小值,答案为f[n-1]和f[n]中较小的一个。
//(这个其实是网上找来的,但是还没得到授权,所以还是放上大佬的链接吧:http://blog.csdn.net/fallen_angel001/article/details/78358915)
代码

#include <cstdio>using namespace std;int a[100006],f[100006];//a数组记录值,f数组记录费用;int n;int min(int a,int b){    if(a<b)return a;    return b;}int max(int a,int b){    if(a>b)return a;    return b;}int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++)        scanf("%d",&a[i]);    for (int i=1;i<=n;i++)    {        f[i]=f[i-1]+a[i];        if (i-2>=0)            f[i]=min(f[i],f[i-2]+a[i]);//如果i-2与i都减为0了,那么i-1自然就不用管了,        if (i-3>=0)            f[i]=min(f[i],f[i-3]+max(a[i],a[i-1]));//如果i-3为0,那么i-1,i都至少要小于等于0;所以费用加上最大的那个数    }    printf("%d",min(f[n],f[n-1]));}
原创粉丝点击