51nod1043 && POJ 2346:幸运号码

来源:互联网 发布:it人的职业规划 编辑:程序博客网 时间:2024/05/20 11:48

Lucky tickets
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 3247 Accepted: 2136

Description

The public transport administration of Ekaterinburg is anxious about the fact that passengers don't like to pay for passage doing their best to avoid the fee. All the measures that had been taken (hard currency premiums for all of the chiefs, increase in conductors' salaries, reduction of number of buses) were in vain. An advisor especially invited from the Ural State University says that personally he doesn't buy tickets because he rarely comes across the lucky ones (a ticket is lucky if the sum of the first three digits in its number equals to the sum of the last three ones). So, the way out is found — of course, tickets must be numbered in sequence, but the number of digits on a ticket may be changed. Say, if there were only two digits, there would have been ten lucky tickets (with numbers 00, 11, ..., 99). Maybe under the circumstances the ratio of the lucky tickets to the common ones is greater? And what if we take four digits? A huge work has brought the long-awaited result: in this case there will be 670 lucky tickets. But what to do if there are six or more digits? 
So you are to save public transport of our city. Write a program that determines a number of lucky tickets for the given number of digits. By the way, there can't be more than 10 digits on one ticket.

Input

Input contains a positive even integer N not greater than 10. It's an amount of digits in a ticket number.

Output

Output should contain a number of tickets such that the sum of the first N/2 digits is equal to the sum of the second half of digits.

Sample Input

4

Sample Output

670

题意是要找幸运数字,所谓幸运数字就是一个n位(n为偶数)的数字,前n/2位每位的数字和与后n/2位的数字和相等。

因为这题第一位0也包括进去了,题目难度减少好多。

然后一看n最大才10,难度一下子下降更多了。就不管dp了,直接打表暴力。

幸好是最大是10,电脑跑了一会才有结果。要是12估计电脑都会跑好久。

暴力代码(n为10时):

#include <iostream>#include <string>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int main(){int i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,result=0;for(i1=0;i1<=9;i1++)for(i2=0;i2<=9;i2++)for(i3=0;i3<=9;i3++)for(i4=0;i4<=9;i4++)for(i5=0;i5<=9;i5++)for(i6=0;i6<=9;i6++)for(i7=0;i7<=9;i7++)for(i8=0;i8<=9;i8++)for(i9=0;i9<=9;i9++)for(i10=0;i10<=9;i10++)if(i1+i2+i3+i4+i5==i6+i7+i8+i9+i10)result++;cout<<result<<endl;system("pause");return 0;}


打表代码:

#include <iostream>#include <string>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int main(){int result[12],n;result[0]=0;result[2]=10;result[4]=670;result[6]=55252;result[8]=4816030;result[10]=432457640;cin>>n;cout<<result[n]<<endl;return 0;}

这么一看这道题还真是水啊。。。


以上是我2015年7月11日时犯下的二逼想法,等到我10月份做到51nod1043的幸运数字时,想起了2346discuss上面的一个dp,于是就顺着那个思路去想了。然后就一直wa。

才发现其实这个dp很简单,远远没有我之前想得那么麻烦。

用dp[i][j]表示i个数的和为j的总数,这里面是包括0开头的情形,有dp[i][j]=dp[i-1][j-k](k从0到9)。很好想,i个数组成总和为j的数量就来自于i-1个数 里面能 在最前面加0到9的数字使得加完之后和为j。

这里面包含了0开头的,把0去掉的方法就是dp[i][j]-dp[i-1][j]。dp[i-1][j]就代表了在i个数中,开头为0的个数,减去就是i个数中开头不为0的个数。原因很明显,i个数和为j与i-1个数和为j,就差了一个位置为0。而这一个位置因为一开始咱们的想法就是在最前面加的数字,所以这个位置就差在了最前面的位置上。

所以根据51nod 又把poj2346的代码改了一下,就是

#include <iostream>  #include <algorithm>  #include <cmath>  #include <vector>  #include <string>  #include <cstring>  #pragma warning(disable:4996)  using namespace std;#define maxn 1005const int mod = 1000000007;long long dp[2][9*maxn];int n;int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);int i,j,k;long long ans;cin>>n;n=n/2;memset(dp,0,sizeof(dp)); //dp[0][1]=1;//此处单独为了1 考虑for(i = 0; i <= 9; ++ i)  {  dp[1][i] = 1;  } for(i=2;i<=n;i++){for(k=0;k<=n*9;k++){long long sum=0;for(j=0;j<=9;j++){if(k>=j)sum = (sum+dp[(i-1)&1][k-j])%mod;elsedp[i&1][k]=0;}dp[i&1][k]=sum;}}ans=0;for(i=0;i<=n*9;i++){ans = (ans+dp[n&1][i]*(dp[n&1][i]))%mod;}cout<<ans<<endl;//system("pause");return 0;}

当然,题目没有要求mod 1e9+7。

然后是51nod1043 幸运号码:

1043 幸运号码
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
 收藏
 取消关注
1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码。
例如:99、1230、123312是幸运号码。
给出一个N,求长度为2N的幸运号码的数量。由于数量很大,输出数量 Mod 10^9 + 7的结果即可。
Input
输入N(1<= N <= 1000)
Output
输出幸运号码的数量 Mod 10^9 + 7
Input示例
1
Output示例
9

代码:

#include <iostream>  #include <algorithm>  #include <cmath>  #include <vector>  #include <string>  #include <cstring>  #pragma warning(disable:4996)  using namespace std;#define maxn 1005const int mod = 1000000007;long long dp[2][9*maxn];int n;int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);int i,j,k;long long ans;cin>>n;memset(dp,0,sizeof(dp)); dp[0][1]=1;//此处单独为了1 考虑for(i = 0; i <= 9; ++ i)  {  dp[1][i] = 1;  } for(i=2;i<=n;i++){for(k=0;k<=n*9;k++){long long sum=0;for(j=0;j<=9;j++){if(k>=j)sum = (sum+dp[(i-1)&1][k-j])%mod;elsedp[i&1][k]=0;}dp[i&1][k]=sum;}}ans=0;for(i=0;i<=n*9;i++){ans = (ans+dp[n&1][i]*(dp[n&1][i]-dp[(n-1)&1][i]))%mod;}cout<<ans<<endl;//system("pause");return 0;}
发现就是不断看自己写过的笔记,也在发现自己得到的成长。三个月的时间,和之前的很多想法都不太一样了。



0 0
原创粉丝点击