1. 程式人生 > >hihoCoder編程練習賽67

hihoCoder編程練習賽67

城市 += onclick -c 兩個 ear aps -- algorithm

題目1 : 序列

時間限制:20000ms 單點時限:1000ms 內存限制:256MB

描述

給定兩個正整數 n, P,求滿足以下兩個條件的長度為 n 的序列 ai 個數:

1. 1 ≤ ai ≤ P

2. 不存在 1 ≤ l ≤ r ≤ n,滿足al + al+1 + ... + ar 是 P 的倍數

由於方案數可能很大,你只需要輸出方案數對 109+7 取模的值

輸入

第一行兩個正整數 n,P

1 ≤ n, P ≤ 104

輸出

輸出方案數對 109+7 取模的值

樣例解釋

滿足條件的序列有兩個:{1,1} 和 {2,2}

樣例輸入

2 3

樣例輸出

2

技術分享圖片
 1 #include <iostream>
 2 #define ll long long
 3 
 4 using namespace std;
 5 
 6 const ll MOD = 1000000007;
 7 
 8 int main()
 9 {
10     ll n, p;
11     while(cin>>n>>p){
12         ll ans = 1;
13         p--;
14         while(n--){
15             ans *= p;
16 ans %= MOD; 17 p--; 18 } 19 cout<<ans<<endl; 20 } 21 22 return 0; 23 }
View Code

題目2 : 彩球

時間限制:20000ms 單點時限:1000ms 內存限制:256MB

描述

有一家商店,一共有 n × k 個彩球。球一共有 n 種顏色,每種顏色的球都是有恰好 k 個,現在你要從這 n×k 個球中選 n 個球,要求他們的顏色互不相同,求有幾種選擇的方案,由於方案數可能很大,你只需要輸出方案數對 P 取模後的值。

輸入

第一行三個正整數 n, k, P

對於50%的數據,有1 ≤ n, k, P ≤ 109

對於100%的數據,有1 ≤ n, k, P ≤ 1018

輸出

輸出方案數對 P 取模後的值

樣例輸入
2 2 100000
樣例輸出
4
技術分享圖片
 1 def quick_pow(a, n, mod):
 2     ans = 1
 3     while(n!=0):
 4         if(n%2==1):
 5             ans = ans*a%mod
 6         a = a*a%mod
 7         n = n // 2
 8     return ans
 9 
10 if __name__ == __main__:
11     n, k, mod = raw_input().strip().split()
12     n = long(n)
13     k = long(k)
14     mod = long(mod)
15     print quick_pow(k, n, mod)
View Code

題目3 : 最優子段

時間限制:20000ms 單點時限:1000ms 內存限制:256MB

描述

給定一個長度為 n 的序列 ai 和兩個整數 A, B,要求你找一對數l, r,要求1 ≤ l ≤ r 且A×(ai+ai+1+...+ar)+B 最大

輸入

第一行三個整數 n, A, B

第二行 n 個整數,第 i 個整數表示 ai

1 ≤ n ≤ 106

-106 ≤ A, B, ai ≤ 106

輸出

輸出最大的A×(ai+ai+1+...+ar)+B

樣例解釋

選擇 (1,1) 或者 (4,4) 都可以

樣例輸入
4 2 3
0 -2 -2 0
樣例輸出
3
技術分享圖片
 1 #include <iostream>
 2 #define ll long long
 3 
 4 using namespace std;
 5 
 6 const int N = 1000010;
 7 
 8 ll arr[N];
 9 
10 ll dp(ll n){
11     ll ans = 0;
12     ll sum = 0;
13     for(int i = 0; i <n; i++){
14         sum += arr[i];
15         ans = max(ans, sum);
16         if(sum < 0)sum = 0;
17     }
18     return ans;
19 }
20 
21 int main()
22 {
23     ll n, A, B;
24     while(cin>>n>>A>>B){
25         for(int i = 0; i < n; i++){
26             cin>>arr[i];
27             if(A<0)arr[i] *= -1;
28         }
29         if(A<0)cout<<-A*dp(n)+B<<endl;
30         else cout<<A*dp(n)+B<<endl;
31     }
32 
33     return 0;
34 }
View Code

題目4 : 公路收費

時間限制:20000ms 單點時限:1000ms 內存限制:256MB

描述

A 國有 n 個城市,第 i 個城市有 ai 個會議代表,這 n 個城市通過 n-$ 條雙向的高速公路連接,保證每兩個城市都可以通過高速公路互相到達,每個人通過一條高速公路都要付相應的費用。

現在 A 國的總統想挑選一個城市作為會議中心,要求全國所有會議代表都到這個城市來,為了方便大家出行,A 國的總統可以讓不超過 k 條高速公路的收費變為 0 。

現在你要安排挑選的城市和免費的高速公路,最小化的所有會議代表的路費總和。

輸入

第一行兩個整數 n, k

第二行 n 個非負整數,第 i 個表示ai

接下來 n-1 行,每行三個整數 u, v, w,描述一條收費為 w 的高速公路 (u, v)

1 ≤ n ≤ 103

0 ≤ k ≤ n-1

1 ≤ w, ai≤ 105

輸出

輸出最小的路費總和

樣例解釋

讓 (2,3) 免費,然後選 2 作為會議城市

樣例輸入
3 1
1 2 3
1 2 1
2 3 2
樣例輸出
1
技術分享圖片
 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 #define ll long long
 7 
 8 using namespace std;
 9 
10 const int N = 1010;
11 const ll INF = 0x3f3f3f3f3f3f3f3f;
12 
13 ll arr[N], sum[N];
14 
15 struct Edge{
16     int to, w, next;
17 }edges[2*N];
18 int head[N], tot;
19 
20 void init(){
21     memset(head, -1, sizeof(head));
22     tot = 0;
23 }
24 
25 void add_edge(int u, int v, int w){
26     edges[tot].to = v;
27     edges[tot].w = w;
28     edges[tot].next = head[u];
29     head[u] = tot++;
30 }
31 
32 vector<ll> vec;
33 int n, k;
34 
35 void dfs(int u, int fa){
36     sum[u] = arr[u];
37     for(int i = head[u]; i != -1; i = edges[i].next){
38         int v = edges[i].to;
39         int w = edges[i].w;
40         if(v != fa){
41             dfs(v, u);
42             sum[u] += sum[v];
43             vec.push_back(sum[v]*w);
44         }
45     }
46 }
47 
48 ll work(int s){
49     vec.clear();
50 
51     dfs(s, 0);
52     sort(vec.begin(), vec.end());
53     ll ans = 0;
54     for(int i = 0; i < n-k-1; i++)
55         ans += vec[i];
56     return ans;
57 }
58 
59 int main()
60 {
61     while(cin>>n>>k){
62         for(int i = 1; i <= n; i++)
63             cin>>arr[i];
64         int u, v, w;
65         init();
66         for(int i = 0; i < n-1; i++){
67             cin>>u>>v>>w;
68             add_edge(u, v, w);
69             add_edge(v, u, w);
70         }
71         ll ans = INF;
72         for(int i = 1; i <= n; i++){
73             ans = min(ans, work(i));
74         }
75         cout<<ans<<endl;
76     }
77     return 0;
78 }
View Code



hihoCoder編程練習賽67