解题报告请见: http://blog.csdn.net/woshi250hua/article/details/7803599
部分题目代码如下:
A题代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[1000] = {
0,1,2,5,10,20,25,50,100,125,200,250,500,1000,1250,2000,2500,5000,10000,12500,20000
,25000,50000,100000,125000,200000,250000,500000,1000000,1250000,2000000,2500000,
5000000,10000000,12500000,20000000,25000000,50000000,100000000,125000000,200000000,
250000000,500000000,1000000000,1250000000,2000000000
};
int main()
{
int i,j,k,cnt = 100;
int n,m,tot;
cnt = 100;
while (scanf("%d%d",&n,&m) != EOF) {
tot = 0;
for (i = 1;i <= cnt; ++i)
if (dp[i] >= n && dp[i] <= m)
tot++;
printf("%d\n",tot);
}
}
B题代码:
//完全背包写法
#include <stdio.h>
#include <string.h>
#define MIN 40
#define MAX 660
int n,m,dp[MAX],ans;
int time[MIN],power[MIN];
int main()
{
int i,j,k;
while (scanf("%d%d",&n,&m) != EOF) {
for (i = 1; i <= n; ++i)
scanf("%d%d",&time[i],&power[i]);
ans = 2147483647;
memset(dp,0,sizeof(dp));
for (i = 1; i <= n; ++i)
for (j = 0; j <= m; ++j)
if (dp[j+time[i]] < dp[j]+j * power[i]) {
dp[j+time[i]] = dp[j] + j * power[i];
if (dp[j+time[i]] >= m && j + time[i] < ans)
ans = j + time[i];
}
printf("%d\n",ans);
}
}
//2B写法
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string.h>
#include <stdlib.h>
using namespace std;
#define MIN 50
#define MAX 500
#define INF 1000000000
#define min(a,b) ((a)<(b)?(a):(b))
int n,m,cost[MIN],pow[MIN];
int dp[MAX][MAX],ans;
int main()
{
int i,j,k,curpow;
int tp2,tpl,cnt;
while (scanf("%d%d",&n,&m) != EOF) {
for (i = 1; i <= n; ++i)
scanf("%d%d",&cost[i],&pow[i]);
for (i = 0; i <= m; ++i)
for (j = 0; j <= m; ++j)
dp[i][j] = INF;
dp[0][0] = 0;
for (i = 0; i <= m; ++i)
for (j = 0; j <= m; ++j)
for (k = 1; k <= n; ++k)
if (dp[i][j] != INF) {
curpow = i + pow[k];
tpl = j + i * cost[k];
if (tpl >= m) tpl = m;
if (curpow >= m) tp2 = m;
else tp2 = curpow;
if (dp[tp2][tpl] >= dp[i][j] + cost[k])
dp[tp2][tpl] = dp[i][j] + cost[k];
}
ans = INF;
for (i = 0; i <= m; ++i)
ans = min(ans,dp[i][m]);
for (i = 1; i <= m; ++i)
for (j = 0; j <= m; ++j)
if (dp[i][j] != INF) {
tpl = dp[i][j],tp2 = m - j;
while (1) {
tpl++,tp2 -= i;
if (tp2 <= 0) {
ans = min(ans,tpl);
break;
}
}
}
printf("%d\n",ans);
}
}
D题代码:
#include <stdio.h>
#include <math.h>
#define E 0.57721566490153286060651209
int main()
{
int i,j,k;
double a,x;
while (scanf("%lf",&a) != EOF) {
x = E;
x *= pow(2,a) - 1;
printf("%1.12e\n",x);
}
}
E题代码:
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define MAX 220
#define max(a,b) ((a)>(b)?(a):(b))
struct node {
int v,len;
};
vector<node> tree[MAX];
int n,m,st,cost[MAX];
int dp[MAX][MAX];
void Initial() {
memset(dp,0,sizeof(dp));
for (int i = 0; i <= n; ++i)
tree[i].clear();
}
void AddEdge(int x,int y,int z) {
node cur;
cur.v = y,cur.len = z;
tree[x].push_back(cur);
}
void Tree_DP(int s,int pa) {
int i,j,k,size;
size = tree[s].size();
for (i = 0; i < size; ++i) {
node cur = tree[s][i];
if (cur.v == pa) continue;
Tree_DP(cur.v,s);
for (j = m; j >= 0; --j)
for (k = 0; k <= m; ++k) {//?????
if (j >= 2*cur.len + k)
dp[s][j] = max(dp[s][j],dp[s][j-2*cur.len-k]+dp[cur.v][k]);
}
}
for (i = 0; i <= m; ++i)
dp[s][i] += cost[s];
}
int main()
{
int i,j,k,a,b,c;
while (scanf("%d",&n) != EOF) {
Initial();
for (i = 1; i <= n; ++i)
scanf("%d",&cost[i]);
for (i = 1; i < n; ++i) {
scanf("%d%d%d",&a,&b,&c);
AddEdge(a,b,c),AddEdge(b,a,c);
}
scanf("%d%d",&st,&m);
Tree_DP(st,-1);
int ans = 0;
for (i = 0; i <= m; ++i)
ans = max(dp[st][i],ans);
printf("%d\n",ans);
}
}
F题代码:
#include <stdio.h>
#include <string.h>
using namespace std;
#define MAX 100010
#define int64 long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
int n, m, p, time;
int64 sum[MAX],ans;
int left, right, dis,gold[MAX];
int64 Solve_AC() {
for (int i = p; i <= n; ++i) {
if (i - p > time) break;
right = i;
dis = max(p - (i - p),1); //i-p时间走到的最远距离
left = max(i - m,1); //要求最远距离不多于m,这两个代表的是一起走的情况
left = max(dis,left); //两个约束条件,最大的那个边界两个条件都符合
left = max(left-(time-(i-p)),1);//这时候右边的人带着左边的人跑
left = min(left,p);
ans = max(ans,sum[right]-sum[left-1]);
}
for (int i = p; i >= 1 && p - i <= time; --i) {
if (p - i > time) break;
left = i;
dis = min(p + (p - i),n); //p-i时间走到的最远距离
right = min(i + m,n); //要求最远距离不多于m,这两个代表的是一起走的情况
right = min(dis,right); //两个约束条件,最大的那个边界两个条件都符合
right = min(right+(time-(p-i)),n); //这时候左边的人带着右边的人跑
right = max(right,p);
ans = max(ans,sum[right]-sum[left-1]);
}
}
int main() {
int i, j, k;
while (scanf("%d%d", &n, &p) != EOF) {
for (i = 1; i <= n; ++i) {
scanf("%d", &gold[i]);
sum[i] = gold[i] + sum[i - 1];
}
scanf("%d%d", &m, &time);
ans = gold[p];
Solve_AC();
printf("%lld\n", ans);
}
}
H题代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define int64 long long
int64 Solve_AC(int64 n) {
if (n == -1) return 0;
int64 x = (int64)sqrt(n);
if (x & 1) x--;
int64 ans = x * (x - 1) / 2;
int64 result = x * x;
if (n >= result + x * 2 + 1)
ans += x * 2 + 1;
else ans += n - x * x + 1;
return ans;
}
int main()
{
int64 n,m;
while (scanf("%lld%lld",&n,&m) != EOF)
printf("%lld\n",Solve_AC(m)-Solve_AC(n-1));
}
I题代码:
#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
#define MIN 101
#define MAX 9010
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
vector<int> mmap[MIN];
int st[MIN],top,vis[MIN];
int tot,ans,mmax,Index,n,m;
int dfn[MIN],low[MIN],isstack[MIN];
void Initial() {
top = Index = 1;
memset(st,0,sizeof(st));
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(isstack,0,sizeof(isstack));
}
void Tarjan(int s,int del) {
int i,j,v,size,cnt;
vis[s] = 1,cnt = 0;
dfn[s] = low[s] = ++Index;
st[++top] = s,isstack[s] = 1;
size = mmap[s].size();
for (i = 0; i < size; ++i) {
v = mmap[s][i];
if (v == del) continue;
if (dfn[v] == 0) {
Tarjan(v,del);
low[s] = min(low[s],low[v]);
}
else if (isstack[v])
low[s] = min(low[s],dfn[v]);
}
if (dfn[s] == low[s]) {
do {
cnt++;
v = st[top--];
isstack[v] = 0;
}while (v != s);
mmax = max(cnt,mmax);
}
}
int main()
{
int i,j,k,a,b;
while (scanf("%d%d",&n,&m) != EOF) {
for (i = 0; i < n; ++i)
mmap[i].clear();
for (i = 0; i < m; ++i) {
scanf("%d%d",&a,&b);
mmap[a].push_back(b);
}
for (ans = n,i = 0; i < n; ++i) {
Initial();
mmax = 0,vis[i] = 1;
for (j = 0; j < n; ++j)
if (!vis[j]) Tarjan(j,i);
if (mmax < 2) mmax = 0;
ans = min(mmax,ans);
if (ans == 0) break;
}
printf("%d\n",ans);
}
}
J题代码:
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string.h>
#include <algorithm>
using namespace std;
#define MIN 50
#define INF 1000000000
#define int64 int
priority_queue<int> qu1,qu2;
int n,m,cost[MIN],sum[MIN];
int Solve_1A() {
int ans = 0,tp;
while (!qu1.empty()) qu1.pop();
qu1.push(0);
for (int i = n; i >= 1; --i) {
if (cost[i] > m) continue;
while (!qu2.empty()) qu2.pop();
while (!qu1.empty()) {
tp = qu1.top(),qu1.pop();
qu2.push(tp);
if (tp + cost[i] <= m) {
if (tp + cost[i] > ans)
ans = tp + cost[i];
qu2.push(tp + cost[i]);
}
}
int flag = 0;
while (!qu2.empty()) {
tp = qu2.top(),qu2.pop();
if (tp + sum[i-1] <= m && flag == 1)
break;
if (tp + sum[i-1] <= m) flag = 1;
qu1.push(tp);
}
}
return ans;
}
int main()
{
int i,j,t,cas = 0;
int u,v,k;
while (scanf("%d%d",&n,&m) != EOF) {
for (i = 1; i <= n; ++i)
scanf("%d",&cost[i]);
sort(cost+1,cost+1+n);
sum[0] = 0;
for (i = 1; i <= n; ++i) {
sum[i] = sum[i-1] + cost[i];
if (sum[i] > m) sum[i] = m + 1;
}
int ans = Solve_1A();
printf("%d\n",ans);
}
}
K题代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX 110000
#define int64 long long
#define INF (0xffffffffffff)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node {
int cost,last;
}arr[MAX];
int64 ans,Min[MAX*3],dp[MAX];
int n,m,tot,cnt,dis[MAX*3];
inline int64 min(int64 a,int64 b) {
return a<b?a:b;
}
void Push_Up(int rt) {
Min[rt] = min(Min[rt<<1],Min[rt<<1|1]);
}
void Build_Tree(int l,int r,int rt) {
if (l == r) {
Min[rt] = (l == n+1 ? 0 : INF);
return;
}
int m = (l + r) >> 1;
Build_Tree(lson);
Build_Tree(rson);
Push_Up(rt);
}
int64 Query_Tree(int L,int R,int l,int r,int rt) {
if (L <= l && r <= R) return Min[rt];
int m = (l + r) >> 1;
int64 temp = INF;
if (m >= L) temp = min(temp,Query_Tree(L,R,lson));
if (m + 1 <= R) temp = min(temp,Query_Tree(L,R,rson));
return temp;
}
void Update(int L,int64 x,int l,int r,int rt) {
if (l == r) {
Min[rt] = min(Min[rt],x);
return;
}
int m = (l + r) >> 1;
if (L <= m) Update(L,x,lson);
else Update(L,x,rson);
Push_Up(rt);
}
int main()
{
int i,j,k,t,cas = 0;
while (scanf("%d",&n) != EOF) {
for (i = 1; i <= n; ++i)
scanf("%d",&arr[i].cost);
for (i = 1; i <= n; ++i)
scanf("%d",&arr[i].last);
Build_Tree(1,n+1,1);
for (i = n; i >= 1; --i) {
j = i + arr[i].last;
if (j >= n + 1) j = n + 1;
dp[i] = Query_Tree(i+1,j,1,n+1,1);
dp[i] += arr[i].cost;
Update(i,dp[i],1,n+1,1);
}
printf("%lld\n",dp[1]);
}
}
测试数据如下:
B题数据
1 1
1 1
2 10
1 1
2 5
3 100
1 10
3 20
10 100
E题数据
2
1 3
1 2 1
1 2
2
1 3
2 1 1
2 1
2
3 3
1 2 1
2 5
2
3 0
1 2 2
2 4
2
3 0
1 2 2
2 4
3
3 3 3
1 2 2
2 3 2
1 5
3
3 3 3
1 2 2
1 3 3
1 5
3
3 3 3
1 2 2
1 3 3
1 10
F题数据
1 1
1
20 20
6 3
101 2 3 3 5 4
0 1
6 3
101 2 3 3 5 4
1 1
6 3
101 2 3 3 5 4
1 4
6 3
101 2 3 3 5 4
2 0
7 4
101 2 3 3 5 4 101
4 3
10 3
101 2 3 3 5 4 101 102 103 104
4 3
10 3
101 2 3 3 5 4 101 102 103 104
4 4
10 7
101 2 3 3 5 4 101 102 103 104
4 4
10 7
101 2 3 3 5 4 101 102 103 104
4 5
10 8
101 2 3 3 5 4 101 102 103 104
4 8
5 5
1 2 3 4 5
6 3
1 2 3 3 5 4
2 1
6 3
1 2 3 3 5 4
2 4
6 3
1 2 3 3 5 4
2 5
6 3
101 2 3 3 5 4
2 5
6 3
101 2 3 3 5 4
2 4
6 3
101 2 3 3 5 4
2 11
I题数据
2 2
0 1
1 0
3 3
0 1
1 2
2 0
4 8
0 1
1 2
2 3
3 0
0 2
2 0
1 3
3 1
J题数据
3 10
8 4 5
3 0
8 4 5
3 100
8 4 5
10 10000
1 2 3 4 5 6 7 8 9 10
10 10000
10000 10000 10000 10000 10000 10000 10000 1000 1000 10000