思路:不要求一次性杀光一个节点里面的所有怪物。 所以我们可以用一个优先队列。优先去杀那些我们当前可以挑战的,然后注意下处理一个房间可能有多个怪物或者无怪物。当我们杀完第x个房间的怪物时候,那么就把x的下一层的怪物加入队列,如果x的下一层出现了空房间[即房间不存在怪物],那么再把该房间当做新的x,继续加入新x的下一层直到出现了有怪物的房间位置。
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<stdio.h> #include<algorithm> #include<vector> #include<queue> #include<functional> #include<cstring> #include<string> using namespace std; typedef long long int LL; const int MAXN = 1005; struct Node {//怪物 int id, def, add_atk; //所在房间,防御值,击杀额外获得的攻击力 }; struct cmp {//按防御值最低并且额外值最高排序[优先队列] bool operator ()(const Node &a, const Node &b) { if (a.def == b.def) { return a.add_atk < b.add_atk; } return a.def > b.def; } }; bool cmp0(Node a, Node b) { //按防御值最低并且额外值最高排序[预处理第0号房间] if (a.def == b.def) { return a.add_atk > b.add_atk; } return a.def < b.def; } vector<Node>GW[MAXN]; //GW[i]:第i个房间的怪物情况 vector<int>G[MAXN]; //图,保存树的结构 int n, m, t, atk, num[MAXN], vis[MAXN]; //点数,怪物数,样例数,每个房间的怪物数,访问数组 bool bfs() { priority_queue<Node, vector<Node>, cmp>Q; //怪物队列 queue<int>inq; //扩展队列,保存x,即保存能扩展下一层的房间号 inq.push(0); vis[0] = 1; while (!inq.empty()) { int top = inq.front(); inq.pop(); if (GW[top].size()) //非空房间 { for (int i = 0; i < GW[top].size(); i++) { //加入此房间的怪物到怪物队列 Q.push(GW[top][i]); } } else //此房间为空房间 { for (int i = 0; i < G[top].size(); i++) { //继续想inq队列加入下一层结点,继续扩展 if (vis[G[top][i]] == 0) { vis[G[top][i]] = 1; inq.push(G[top][i]); } } } } while (!Q.empty()) { Node front = Q.top(); Q.pop(); if (atk <= front.def) //当前最优都无法击杀,那么后面肯定击杀不了。 { return false; } atk += front.add_atk; num[front.id]--; if (num[front.id] == 0) //此房间的怪物已经击杀完或者是空房间 { for (int i = 0; i < G[front.id].size(); i++) //同上处理 { if (vis[G[front.id][i]] == 0) { vis[G[front.id][i]] = 1; inq.push(G[front.id][i]); } } while (!inq.empty()) { int top = inq.front(); inq.pop(); if (GW[top].size()) { for (int i = 0; i < GW[top].size(); i++) { Q.push(GW[top][i]); } } else { for (int i = 0; i < G[top].size(); i++) { if (vis[G[top][i]] == 0) { vis[G[top][i]] = 1; inq.push(G[top][i]); } } } } } } return true; //全部怪物击杀完成 } void init() { memset(num, 0, sizeof(num)); memset(vis, 0, sizeof(vis)); for (int i = 0; i <= n; i++) { G[i].clear(); GW[i].clear(); } } int main() { scanf("%d", &t); while (t--) { init(); scanf("%d%d", &n, &m); for (int i = 0; i < n - 1; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } scanf("%d", &atk); for (int i = 0; i < m; i++) { Node temp; scanf("%d%d%d", &temp.id, &temp.def, &temp.add_atk); GW[temp.id].push_back(temp); num[temp.id]++; } if (bfs()) { printf("Oh yes.\n"); } else { printf("Good Good Study,Day Day Up.\n"); } } return 0; }
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<stdio.h> #include<set> #include<vector> using namespace std; typedef long long int LL; const int MAXN = 10000 + 5; const int MAXZ = 105; struct Node { int w, v; //价格,攻击力 int id, buff; //是否有buff加成 Node(int b = 0, int c = 0, int d = -1, int e = 0) :w(b), v(c), id(d), buff(c){}; void init(int a = 0, int b = 0, int c = -1, int d = -1) { w = a; v = b; id = c; buff = d; } }; Node Tk[MAXZ], Ss[MAXZ], Dw[MAXZ], Sw[MAXZ], TS[3][MAXN]; //头盔,首饰,单手武器,双手武器,TS[1]:防具组,TS[2]:武器组 int main() { int t; scanf("%d", &t); while (t--) { int m, a, b, c, d, ts = 0, ts2 = 0; int wei, val, Buff, Id; scanf("%d%d%d%d%d", &m, &a, &b, &c, &d); for (int i = 0; i<a; i++) //头盔 { scanf("%d%d", &wei, &val); Node temp(wei, val, 0, 0); Tk[i] = temp; TS[1][ts++] = temp; //防具组:只选一个头盔 } for (int i = 0; i<b; i++) //首饰 { scanf("%d%d%d%d", &wei, &val, &Id, &Buff); Node temp(Node(wei, val, Id, Buff)); Ss[i] = temp; TS[1][ts++] = temp; //防具组:只选一个首饰 if (Id == -1 || Buff <= 0) { continue; } temp.init(Ss[i].w + Tk[Id].w, Ss[i].v + Tk[Id].v + Buff, 0, 0); TS[1][ts++] = temp; //防具组:有buff加成的头盔+首饰 } for (int i = 0; i<a; i++) //防具组:头盔+首饰 { for (int j = 0; j<b; j++) { Node temp(Node(Tk[i].w + Ss[j].w, Tk[i].v + Ss[j].v, 0, 0)); TS[1][ts++] = temp; } } for (int i = 0; i<c; i++) //单手武器 { scanf("%d%d", &wei, &val); Node temp(wei, val, 0, 0); TS[2][ts2++] = temp; //武器组:只选一个单手武器 Dw[i] = temp; } for (int i = 0; i<c; i++) //武器组:一个单手武器+一个单手武器=双手武器 { for (int j = i + 1; j<c; j++)//因为每种只有一个,所以j要从i+1开始 { Node temp(Dw[i].w + Dw[j].w, Dw[i].v + Dw[j].v); TS[2][ts2++] = temp; } } for (int i = 0; i<d; i++) //双手武器 { scanf("%d%d", &wei, &val); Node temp(wei, val, 0, 0); TS[2][ts2++] = temp; //武器组:只选一个双手武器。 } //贪心求法: LL ans = 0; for (int i = 0; i<ts; i++) {//在限有的金币下,x=只选防具的最大攻击力 if (TS[1][i].w <= m) //在限有的金币下 { ans = max(ans, 1LL * TS[1][i].v); } } for (int i = 0; i<ts2; i++) { //在限有的金币下,y=只选武器的最大攻击力 if (TS[2][i].w <= m) //在限有的金币下 { ans = max(ans, 1LL * TS[2][i].v); } } for (int i = 0; i<ts; i++) {//z=选防具和武器搭配的最大攻击力 for (int j = 0; j<ts2; j++) { if (TS[1][i].w + TS[2][j].w <= m) //在限有的金币下 { ans = max(ans, 1LL * (TS[1][i].v + TS[2][j].v)); } } } printf("%lld\n", ans); //ans=max(x,y,z) //////////////////////////分组背包求法////////////////////////////////// int dp[3][MAXN]; memset(dp, 0, sizeof(dp)); for (int i = 1; i <= 2; i++) { for (int k = 0; k <= m; k++) { dp[i][k] = dp[i - 1][k]; } for (int k = 0; k<(i == 1 ? ts : ts2); k++) { for (int j = m; j >= TS[i][k].w; j--) { dp[i][j] = max(dp[i][j], dp[i - 1][j - TS[i][k].w] + TS[i][k].v); } } } printf("%d\n", dp[2][m]); } return 0; }
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<stdio.h> #include<algorithm> #include<string> #include<cstring> #include<stack> #include<queue> using namespace std; typedef long long int LL; const int MAXN = 100 + 5; const int INF = 0x3f3f3f3f; const int MOD = 1000000009; int D[MAXN][MAXN], g[MAXN][MAXN]; //D:起点到其他点的最短路距离 int n, minval, dist[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 }; //minval:起点到终点的最短路距离,dist:方向向量 struct Node { int x, y; int val; }; struct cmp { bool operator()(const Node &a, const Node &b) { return a.val > b.val; } }; bool check(int x, int y)//是否越界 { return x >= 1 && x <= n&&y >= 1 && y <= n; } void bfs(Node start) { priority_queue<Node, vector<Node>, cmp>Q; memset(D, -1, sizeof(D)); Q.push(start); D[start.x][start.y] = start.val; while (!Q.empty()) { Node t = Q.top(); Q.pop(); Node next; for (int i = 0; i < 4; i++) { next.x = t.x + dist[i][0]; next.y = t.y + dist[i][1]; if (check(next.x, next.y) && D[next.x][next.y] == -1 && next.x + next.y <= n + 1) { //g[next.x][next.y]为当前值,g[n - next.y + 1][n - next.x + 1]为对角线对称点值 next.val = t.val + g[next.x][next.y] + (next.x + next.y == n + 1 ? 0 : g[n - next.y + 1][n - next.x + 1]); D[next.x][next.y] = next.val; Q.push(next); } } } minval = INF; for (int i = 1; i <= n; i++)//找到最短路 { minval = min(minval, D[i][n + 1 - i]); } } int dp[MAXN][MAXN]; int dfs(int x, int y) { if (dp[x][y] != -1)//记忆化搜索 { return dp[x][y]; } int nextx, nexty, cnt = 0; for (int i = 0; i < 4; i++) { nextx = x + dist[i][0]; nexty = y + dist[i][1]; if (check(nextx, nexty) && nextx + nexty <= n + 1 && D[nextx][nexty] + g[x][y] + (x + y == n + 1 ? 0 : g[n - y + 1][n - x + 1]) == D[x][y]) { cnt = (cnt + dfs(nextx, nexty)) % MOD; } } dp[x][y] = cnt%MOD; return dp[x][y]; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &g[i][j]); } } Node start; start.x = 1; start.y = 1, start.val = g[1][1] + g[n][n]; //起点。 bfs(start); //求(1,1)到其他点的最短路距离 /*for (int i = 1; i <= n; i++) //Debug { for (int j = 1; j <= n; j++) { printf("%d ", D[i][j]); } printf("\n"); }*/ memset(dp, -1, sizeof(dp)); LL ans = 0; dp[1][1] = 1; for (int i = 1; i <= n; i++) { if (D[i][n + 1 - i] == minval) { ans = (ans + dfs(i, n + 1 - i)) % MOD; } } printf("%lld\n", ans); } return 0; }
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<stdio.h> #include<set> using namespace std; typedef long long int LL; const int MAXN=100000+5; char str[MAXN]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%s",str); bool flag=true; for(int i=0;i<strlen(str)-1;i++) { if(str[i]=='#'&&str[i+1]=='#') { flag=false; break; } } printf(flag?"yes\n":"no\n"); } return 0; }
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<stdio.h> #include<algorithm> #include<string> #include<cstring> #include<stack> #include<queue> using namespace std; typedef long long int LL; const int MAXN = 1000000 + 5; struct Node { int H; int id; }A[MAXN]; void solve(int n) { LL ans = 0; stack<Node>st; for (int i = 0; i < n; i++) { if (st.empty()) { st.push(A[i]); } else { LL top_h = 0; LL cnt = 0, tot = 0; while (!st.empty()) { Node tmp = st.top(); top_h = tmp.H; if (A[i].H > tmp.H) { cnt += 1LL * (A[i].id - tmp.id); tot += 1LL * (A[i].id - tmp.id)*tmp.H; A[i].id = tmp.id; st.pop(); } else { break; } } ans += 1LL * (cnt* min(1LL * A[i].H, top_h) - tot); st.push(A[i]); } } printf("%lld\n", ans); } int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &A[i].H); A[i].id = i; } solve(n); } return 0; }
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<stdio.h> #include<algorithm> #include<string> #include<cstring> using namespace std; typedef long long int LL; const int MAXM = 1e9; LL p, ans; int n, cnt, num[55], temp[55], vis[55]; LL gcd(LL x, LL y) { return y ? gcd(y, x % y) : x; } void DFS(LL i, LL w, LL k) {//i:当前的位置,w:之前集合的最小公倍数,k:奇偶 if (w > MAXM) //剪枝。 { return; } for (; i < cnt; i++) { p = num[i] / gcd(num[i], w) * w; ans += k*(MAXM / p); DFS(i + 1, p, -k); } } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &n); cnt = 0; bool one = false; memset(vis, 0, sizeof(vis)); for (int i = 0; i < n; i++) { scanf("%d", &temp[i]); if (temp[i] == 0) { vis[temp[i]] = 1; } if (temp[i] == 1)//出现1 { one = true; } } if (one) { printf("0\n"); continue; } sort(temp, temp + n); for (int i = 0; i < n; i++) //删除里面的倍数 { for (int j = i + 1; j < n; j++) { if (vis[i] == 0 && vis[j] == 0 && temp[j] % temp[i] == 0) { vis[j] = 1; } } if (vis[i] == 0) { num[cnt++] = temp[i]; } } ans = 0; DFS(0, 1, 1); printf("%lld\n", MAXM - ans); } }
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<stdio.h> #include<set> using namespace std; typedef long long int LL; const int MAXN = 10000; char str[MAXN]; int main() { int t; scanf("%d", &t); getchar(); while (t--) { gets(str); set<char>word; for (int i = 0; i<strlen(str); i++) { if (str[i] >= 'a'&&str[i] <= 'z'&&!word.count(str[i])) { word.insert(str[i]); } } printf("%d\n", word.size()); } return 0; }