第一题:http://acmore.net/problem.php?id=1485
这题的关键就是如何求 一个长度为n的蛋糕,切成 n个单位长度为1的蛋糕。 通过递可以发现把,一个长度为n的蛋糕切成n个单位蛋糕所花时间s=(a)*(a-1)/2;
那么对于每个人服务的结束时间就可以求出。然后按结束时间排序(与活动选择类似)。
第二题:http://acmore.net/problem.php?id=1486
这题 可以用动态规划解决。dp[i] //表示 前i个单词构成的最小整齐度。 那么
dp[i]=min(dp[k-1],val[k][i]); (1<=k<=i)
val[k][i] .表示val[k][i]代表将k到i的单词写入一行时,该行的多余空格数的立方。
第三题:http://www.acmore.net/problem.php?id=1487
题目有点小问题,当[b,a)时交换两数变成[a,b)即可。
题目的主要思想是对输入的覆盖段做预处理(将能合并成一段的合并,如[1,3)和[2,6),可合并成[1,6))。
开一个ans[200005],对输入的覆盖段[a,b),有ans[a]=b(若有[a,c),c>b则更新为ans[a]=c);并记录一个最早的开始的覆盖段[L,K)则min=L;max=K;
扫描ans[],当(i>min&&i<max)(即此点在覆盖段内)时num++(用num统计覆盖的点数。);同时更新max.
输出为n-num.
第四题:http://www.acmore.net/problem.php?id=1488
数位DP入门题。 数位DP一直不怎么会。今天看了别人的思路。稍微有了一点感觉、
首先需要一个辅助数组f[i] 记录前i位里有多少个1。比如 f[2]为 0-99里一共有多少个1. 这个辅助数组的状态转移方程为
f[i]=f[i-1]*10 + pow(10,i-1); 这个公式的推导是这样推的。 可以在第i位添加的数为(0-9)也就是10个。 那么 f[i-1]*10 表示无论 第i位是什么数。
f[i]里的1的个数都会增加 f[i-1]*10个 。而这样计算将少计算末尾为1的方法数。所以pow(10,i-1) 表示末尾是1.其他位为任意数的方法数。
求出了 f[i]. 那么现在只需要找出整数1-n 之间有多少个1即可。
求1-n之间有多少个1 ,就是把n分解转化求f[i]的形式。
例如n = 122;
1 那么 最高位为1 可以求出 0-99里含有多少个1. 同时记录没有计算的1的个数 temp++; 也就是 112里面 0-99的个数已经求出。 ans+=f[i-1];而大于99的1还没计算。
2次高位为2的时候。这时候就要把最高位为1的个数加上temp*1*10。因为次高位为2,这里的求法分为两步1可以求出 0-9 里含有多少个1(这里的0-9指的是100-109)
2 还有10-19里的个数(这里的10-19指的是 110-119), 公式为。ans+=a[i]*f[i-1]+pow((LL)10,i-1); ( i为当前位数)
3 同理求出最后一位
参考代码:http://codepad.org/UmTfp8tQ
第五题:http://www.acmore.net/problem.php?id=1489
由于数据较小。最多的排列情况也只有:9!
所以可以采用暴力的方法。
首先,可以把这个问题看成一个完全图,每位数字看成一个点。
然后从每一个点(第一个点不能从0开始)出发进行遍历即可。
code:http://codepad.org/KbKn7Geh