1004 Permutation Counting
题目:
https://vjudge.net/contest/390380#problem/D
思路:
代码:
学习:https://blog.csdn.net/qq_44644225/article/details/108139371
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int maxn = 5000 + 5;
int b[maxn];
int dp[maxn][maxn], sum[maxn][maxn];
int main() {
int t,n;scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=2;i<=n;i++){
scanf("%d",&b[i]);///如果b[i]=0 a[i]>b[i],else a[i]<b[i]
}
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
dp[1][1]=1;/// 第一个数在第一个位置
int ans=0;
for(int i=2;i<=n;i++){
for(int j=1;j<i;j++){
if(b[i]==0){
sum[i][j+1]=(sum[i][j+1]+dp[i-1][j])%mod;
}
///b[i] > b[i-1],只能填在前一个数的后面
///所以sum[i][j+1]代表第i-1个数填在j位的方案数
else{
sum[i][j] = (sum[i][j] + dp[i-1][j])%mod;
}
///b[i] < b[i-1],可以代替前一个数的位置,填在第j位
///所以sum[i][j]代表第i-1个数填在j位的方案数
}
if(b[i]==0){
for(int j=1;j<=i;j++)
dp[i][j]=((dp[i][j]+sum[i][j])%mod+dp[i][j-1])%mod;
///b[i] > b[i-1],sum[i][j]代表第i-1个数填在j-1位的方案数
///dp[i][j-1]代表第i-1个数填在(1~j-2)这个位置的方案数,因为dp[i][j]是一步步加上sum[i][j]累加来的。
///那么第i个数在j这个位置的方案数一共要加上sum[i][j]和dp[i][j-1]
}else{
for(int j=i;j>=1;j--)
dp[i][j]=((dp[i][j]+sum[i][j])%mod+dp[i][j+1])%mod;
}
}
for(int i=1;i<=n;i++)
ans=(ans+dp[n][i])%mod;
printf("%lld\n",ans);
}
}
1011 Task Scheduler
题目:
https://vjudge.net/contest/390380#problem/K
思路:
证明参考:https://blog.csdn.net/xuxiaobo1234/article/details/108140387
代码:
学习:https://blog.csdn.net/qq_44644225/article/details/108139371
#include<bits/stdc++.h>
using namespace std;
struct h{
int d;
int w;
}e[21000];
bool c(h a,h b){
if(a.w!=b.w){
return a.w>b.w;
}else{
return a.d<b.d;
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%d",&e[i].w);
e[i].d=i;
}
if(k==0){
printf("1");
for(int i=2;i<=n;i++) printf(" %d",i);
printf("\n");
continue;
}
sort(e+1,e+n+1,c);
printf("%d",e[1].d);
for(int i=2;i<=n;i++)
printf(" %d",e[i].d);
printf("\n");
}
}