数数
题目描述
“你已经是一个成熟的孩子了,要学会自己数数了!”
示例1
输入
1
1
输出
1 1
题解:计算公式,进行化简,第一个等差数列求和,第二个阶乘的n次方。
1×1+1×2+1×3+…+1×n + 2×1+2×2+2×3+…+2×n +…+ n×1+n×2+n×3 +…+ n×n
= 1×n×(n+1)/2 + 2×n×(n+1)/2 + …n×n×(n+1)/2。
1×1 × 1×2 × 1×3 ×…× 1×n × 2×1 × 2×2 × 2×3 × …× 2×n ×…×n×1 × n×2 × n*3 × …× n×n = (n!)^(2×n)。
奇数列上竖着相乘是n个n!,
偶数列上横着相乘是n个n!, 合并起来是(n!)^(2×n)。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=998244353;
ll poww(ll a,ll b) // 快速幂
{
ll ans=1,base=a;
while(b!=0)
{
if(b&1!=0) ans=ans*base%mod;
base=base*base%mod;
b>>=1;
}
ans=ans%mod;
return ans;
}
int main()
{
ll t, n;
scanf("%lld", &t);
while(t--)
{
scanf("%lld", &n);
ll ans1=0,ans2=1;
ll sum = ((n*(n+1))/2) %mod;
for(int i=1; i<=n; i++) {
ans1 = (ans1 + i*sum) %mod;
ans2 = (ans2*i) %mod;
}
printf("%lld %lld\n", ans1, poww(ans2, 2*n)%mod);
}
return 0;
}
矩阵消除游戏
示例1
输入
3 3 2
101 1 102
1 202 1
100 8 100
输出
414
思路:以二进制01串表示行的可选可不选如0010表示1, 2,4行不选,3行选,选的方法就是从000——111总共0-2^n-1种组合
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define space putchar(' ')
#define enter putchar('\n')
typedef pair<int,int> PII;
const int inf = 0x3f3f3f3f, mod=1e9+7, N=5e5+10;
ll gcd(ll a,ll b){
return b==0 ? a:gcd(b,a%b);
}
ll lcm(ll a,ll b){
return a*(b/gcd(a,b));
}
template <class T>
void read(T &x)
{
char c;
bool op = 0;
while(c=getchar(), c<'0' || c>'9')
if(c == '-') op = 1;
x = c-'0';
while(c=getchar(), c>='0' && c<='9')
x = x*10 + c-'0';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x<0) x=-x, putchar('-');
if(x>=10) write(x/10);
putchar('0' + x%10);
}
bool b[20];
ll s1[20],s2[20];
ll a[30][30],cnt;
int tran(int x)
{
memset(b,0,sizeof b);
cnt=0;
int index=1;
while(x) {
if(x&1) {
cnt++;
b[index]=1;
}
x>>=1;
index++;
}
return cnt;
}
int main()
{
int n,m,k;
read(n),read(m),read(k);
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
read(a[i][j]);
s1[i]+=a[i][j];
}
}
if(k>n) k=n;
if(k>m) k=m;
int fw=(1<<n)-1;
ll ans=0;
for(int p=0;p<=fw;p++)
{
int n1 = tran(p);
int n2 = k-n1;
ll sum=0;
if(n1>k||n2<0)continue;
for(int i=1;i<=n;i++)
if(b[i]) sum+=s1[i];
memset(s2,0,sizeof s2);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(!b[j])s2[i]+=a[j][i];
sort(s2+1,s2+m+1);
for(int i=1,j=m; i<=n2; i++,j--) sum+=s2[j];
ans=max(ans,sum);
}
write(ans);
return 0;
}