1 任务安排
manage.in/.out/.cpp
(题目原型:洛谷:P2920 [USACO08NOV]时间管理Time Management)
1.1 问题描述
你有 N 个工作,同一时刻只能做一个任务, 其中每个工作有其所需时间, 及完成的 Deadline(截止时间), 问要完成所有工作, 最迟要从什么时候开
始。
你最早可以从时间 0 开始工作。
1.2 输入格式
第一行一个整数 N,表示任务数量接下来 n 行,每行两个整数,T i ,S i ,分别表示该任务的持续时间和截
止时间。
1.3 输出格式
输出一个整数,表示最晚的开始时间,如果不能完成,输出-1。1.4 样例输入
43 5
8 14
5 20
1 16
1.5 样例输出
21.6 数据规模及约定
对于 40% 的数据,N <= 20对于 60% 的数据,N <= 1000
对于 100% 的数据,1<= N <= 100000
1<= T i <= 100000
1<= S i <= 1000000
还有二分做法。。
#include
#include
#include
#include
#define MAXN 100005
using namespace std;
struct DATA { int T,S; } a[MAXN];
inline void read(int &x) {
x = 0; register char c = getchar();
while(c > '9' || c < '0') c = getchar();
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
}
inline bool cmp (DATA a,DATA b) { return a.S < b.S; }
int main(int argc,char *argv[]) {
freopen("manage.in","r",stdin);
freopen("manage.out","w",stdout);
int n; read(n);
for(int i=1; i<=n; ++i) read(a[i].T),read(a[i].S);
sort(a + 1, a + n + 1, cmp);
int Ans = a[n].S;
for(int i=n; i>=1; --i) {
Ans = min(Ans,a[i].S);
Ans -= a[i].T;
}
if(Ans < 0 ) Ans = -1;
printf("%d\n",Ans);
fclose(stdin); fclose(stdout);
return 0;
}
2 小 a 的强迫症
qiang.in/.out/.cpp2.1 问题描述
小 a 是一名强迫症患者,现在他要给一群带颜色的珠子排成一列,现在有 N 种颜色,其中第 i 种颜色的柱子有 num(i) 个。要求排列中第 i 种颜色
珠子的最后一个珠子,一定要排在第 i+1 种颜色的最后一个珠子之前。问
有多少种排列珠子的方案。
2.2 输入格式
第一行一个整数 N,表示珠子颜色数量第二行 N 个整数,分别表示每种珠子的颜色数量
2.3 输出格式
排列方案数,对 998244353 取余2.4 样例输入
32 2 1
2.5 样例输出
32.6 数据规模及约定
共 3 种排列方案:1 2 1 2 3
1 1 2 2 3
2 1 1 2 3
对于 40% 的数据,所有珠子数量和小于 15
对于 80% 的数据,N <= 1000,所有珠子数量和小于 5000
对于 100% 的数据,N <= 100000,所有珠子数量和小于 500000
#include
#include
#include
#include
#include
#define MAXN 100005 #define N 500005 #define Mod 998244353 using namespace std; typedef long long LL; int num[MAXN],sum[MAXN]; LL fac[N],Inv[N],inv[N]; // inv[i] i 模 Mod 意义下的逆元 // Inv[i] i! 模 Mod 意义下的逆元 inline void read(int &x) { x = 0; register char c = getchar(); while(c > '9' || c < '0') c = getchar(); while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } } void Pre() { fac[0] = fac[1] = 1; inv[0] = inv[1] = 1; Inv[0] = Inv[1] = 1; for(int i=2; i<=500001; ++i) { fac[i] = ( fac[i-1] % Mod * i % Mod ) % Mod; inv[i] = (1LL * (-(Mod / i) * inv[Mod % i])) % Mod; if(inv[i] < 0) inv[i] += Mod; Inv[i] = ( Inv[i-1] % Mod * inv[i] % Mod ) % Mod; if(Inv[i] < 0) Inv[i] += Mod; } } LL C(int n,int m) { LL ret; ret = ( (fac[n] % Mod * Inv[m] % Mod) % Mod * Inv[n - m] % Mod ) % Mod; return ret; } int main(int argc,char *argv[]) { freopen("qiang.in","r",stdin); freopen("qiang.out","w",stdout); int n; read(n); Pre(); for(int i=1; i<=n; ++i) read(num[i]),sum[i] = sum[i-1] + num[i]; LL Ans = 1; for(int i=2; i<=n; ++i) Ans = (Ans % Mod * C(sum[i]-1,num[i]-1) % Mod) % Mod; printf("%I64d\n",Ans); fclose(stdin); fclose(stdout); return 0; } //快速幂求逆元 跑得快 亲测 #include
#include
#include
#include
#include
#define MAXN 100005 #define N 500005 #define Mod 998244353 using namespace std; typedef long long LL; int num[MAXN],sum[MAXN]; LL fac[N]; // inv[i] i 模 Mod 意义下的逆元 // Inv[i] i! 模 Mod 意义下的逆元 inline void read(int &x) { x = 0; register char c = getchar(); while(c > '9' || c < '0') c = getchar(); while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } } void Pre() { fac[0] = fac[1] = 1; for(int i=2; i<=500001; ++i) fac[i] = ( fac[i-1] % Mod * i % Mod ) % Mod; } LL Fast_Pow(LL a,LL b) { LL ret = 1; while(b) { if(b&1) ret = ret * a % Mod; a = a * a % Mod; b >>= 1; } return ret; } LL C(int n,int m) { LL ret; ret = ( (fac[n] % Mod * Fast_Pow(fac[m],Mod-2) % Mod) % Mod * Fast_Pow(fac[n-m],Mod-2) % Mod ) % Mod; return ret; } int main(int argc,char *argv[]) { freopen("qiang.in","r",stdin); freopen("qiang.out","w",stdout); int n; read(n); Pre(); for(int i=1; i<=n; ++i) read(num[i]),sum[i] = sum[i-1] + num[i]; LL Ans = 1; for(int i=2; i<=n; ++i) Ans = (Ans % Mod * C(sum[i]-1,num[i]-1) % Mod) % Mod; printf("%I64d\n",Ans); fclose(stdin); fclose(stdout); return 0; }