HDU-4301 Divide Chocolate(dp)
题意:给一个2*n的巧克力,把他分成k块,问有几种分法。(n<=1000)
题解:dp,状态比较多,dp[i][j][k]表示前i列分成了j块,k=0表示第i列上下相连,k=1表示第i列上下分开,的种类数
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 100000007
using namespace std;
int dp[1010][1010*2][2];
int n, k;
int main(){
int T;
memset(dp, 0, sizeof(dp));
dp[1][2][1] = 1;
dp[1][1][0] = 1;
for(int i = 2; i<=1000; i++){
for(int j = 1; j<=2*i; j++){
dp[i][j][0] = (dp[i-1][j][0]+dp[i-1][j][1]*2+dp[i-1][j-1][0]+dp[i-1][j-1][1])%mod;
dp[i][j][1] = (dp[i-1][j][1]+dp[i-1][j-1][1]*2+dp[i-1][j-1][0]*2)%mod;
if(j>=2) dp[i][j][1] = (dp[i][j][1]+dp[i-1][j-2][1]+dp[i-1][j-2][0])%mod;
}
}
scanf("%d", &T);
while(T--){
scanf("%d %d", &n, &k);
printf("%d\n", (dp[n][k][0]+dp[n][k][1])%mod);
}
return 0;
}
HDU-4302 Holedox Eating(树状数组+二分)
题意:在一个序列上有两种操作,0 x 表示在x这个位置加一块事物,1 表示Holedox要吃掉离他最近的一块事物,如果最近的有两种选择,则他选择前进方向是原方向的那一块事物。
题解:用树状数组+二分可以求出当前位置右边和左边第一个大于0的元素的位置
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int c[100010*4];
int L, n;
int lowbit(int x){
return x&(-x);
}
void update(int i, int x){
while(i<=100010){
c[i] = c[i]+x;
i += lowbit(i);
}
}
int sum(int x){
int sum = 0;
while(x>0){
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int main(){
int T;
scanf("%d", &T);
for(int t = 1; t<=T; t++){
memset(c, 0, sizeof(c));
int now = 1;
int flag = 1;
int dis = 0;
scanf("%d%d", &L, &n);
L++;
//update(1, 1);
//cout<<sum(1)-sum(0)<<endl;
while(n--){
int ch, x;
scanf("%d", &ch);
if(ch == 0){
scanf("%d", &x);
x++;
update(x, 1);
}
else{
if(sum(now)-sum(now-1)>0){
//cout<<"! "<<now<<endl;
update(now, -1);
//cout<<"asd"<<endl;
continue;
}
else if(sum(L)-sum(now) == 0 && sum(now-1)-sum(0) == 0){
// cout<<"! "<<sum(L)<<endl;
//cout<<"gg"<<endl;
continue;
}
else{
int l = now+1, r = L;
int temp1 = 0x3f3f3f3f;
while(l<=r){
int mid = (l+r)>>1;
if(sum(mid)-sum(now)>=1){
temp1 = mid;
r = mid-1;
}
else{
l = mid+1;
}
}
l = 1; r = now-1;
int temp2 = 0;
while(l<=r){
int mid = (l+r)>>1;
if(sum(now-1)-sum(mid-1)>=1){
temp2 = mid;
l = mid+1;
}
else{
r = mid-1;
}
}
//cout<<now<<" "<<temp1<<" "<<temp2<<endl;
if(temp1 == 0x3f3f3f3f){
dis+=now-temp2;
now = temp2;
flag = 0;
update(now, -1);
continue;
}
if(temp2 == 0){
dis+=temp1-now;
now = temp1;
flag = 1;
update(now, -1);
continue;
}
if(now-temp2 == temp1-now){
if(flag == 1){
dis+=temp1-now;
now = temp1;
update(now, -1);
}
else{
dis+=now-temp2;
now = temp2;
update(now, -1);
}
}
else if(now-temp2>temp1-now){
dis+=temp1-now;
now = temp1;
flag = 1;
update(now, -1);
}
else if(now-temp2<temp1-now){
dis+=now-temp2;
now = temp2;
flag = 0;
update(now, -1);
}
}
}
//cout<<" "<<dis<<endl;
}
printf("Case %d: %d\n", t, dis);
}
return 0;
}
HDU-4308 Saving Princess claire_(简单bfs)
题意:从Y走到C,#表示障碍,*表示要花费c时间,从一个P可以通道任意一个P,求最短花费时间
题解:碰到第一个P就把所有P入队
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int n, m, c;
char ma[5010][5010];
bool vis[5010][5010];
int yx, yy, cx, cy;
int cnt;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
struct node{
int x, y;
int dis;
}p[5010];
void solve(){
memset(vis, false, sizeof(vis));
queue<node> que;
while(que.size()) que.pop();
node q;
q.x = yx; q.y = yy; q.dis = 0;
vis[q.x][q.y] = true;
que.push(q);
while(que.size()){
node f = que.front();
que.pop();
if(f.x == cx && f.y == cy){
printf("%d\n", f.dis);
return;
}
for(int i = 0; i<4; i++){
int fx = f.x+dx[i];
int fy = f.y+dy[i];
if(fx>=1 && fx<=n && fy>=1 && fy<=m && ma[fx][fy]!='#' && vis[fx][fy] == false){
if(ma[fx][fy] == 'P'){
for(int j = 0; j<cnt; j++){
q.x = p[j].x; q.y = p[j].y; q.dis = f.dis;
vis[q.x][q.y] = 1;
que.push(q);
}
}
if(ma[fx][fy] == '*'){
q.x = fx; q.y = fy; q.dis = f.dis+c;
vis[q.x][q.y] = 1;
que.push(q);
}
if(ma[fx][fy] == 'C'){
printf("%d\n", f.dis);
return;
}
}
}
}
printf("Damn teoy!\n");
}
int main(){
while(scanf("%d %d %d", &n, &m, &c) != EOF){
cnt = 0;
for(int i = 1; i<=n; i++){
scanf("%s", ma[i]+1);
}
for(int i = 1; i<=n; i++){
for(int j = 1; j<=m; j++){
if(ma[i][j] == 'Y'){
yx = i; yy = j;
}
if(ma[i][j] == 'C'){
cx = i; cy = j;
}
if(ma[i][j] == 'P'){
p[cnt].x = i; p[cnt++].y = j;
}
}
}
solve();
}
return 0;
}