8月14号的练习:HDU 1789&&HDU 1846&&HDU 1527&&POJ 1844&&HDU 1142

Doing Homework again HDU 1789

可以用贪心做(网上搜了发现都是用贪心,DP就这么难???)

思路:the reduced scores.从大到小排序,(相同就把the deadlines of the subjects从小到大排序

这里可保证耗分数最多的给完成,留下的分数最低。

其实这贪心很容易想到。但最坑的是!只给出一个N,我还以为the deadlines of the subjects就在这里取呢!(1~N)

之后才发现天数和所扣的分数未知!

幸好这个天数就在1000左右,如果在大点肯定超时

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<string.h>
 5 using namespace std;
 6 struct line
 7 {
 8     int x;
 9     int y;
10 }a[1005];
11 bool comp1(line i,line j)
12 {
13     if(i.y!=j.y)
14         return i.y>j.y;
15     return i.x<j.x;
16 }
17 int main()
18 {
19     int n,i,t,sum,d,b[1005];
20     scanf("%d",&t);
21     while(t--)
22     {
23         scanf("%d",&n);
24         memset(b,0,sizeof(b));
25         for(i=1;i<=n;i++)
26             scanf("%d",&a[i].x);
27         for(i=1;i<=n;i++)
28             scanf("%d",&a[i].y);
29         sort(a+1,a+1+n,comp1);
30         sum=0;
31         for(i=1;i<=n;i++)
32         {
33             d=0;
34             if(b[a[i].x]==0)
35                 b[a[i].x]=1;
36             else
37             {
38                 while(b[a[i].x]==1)
39                 {
40                     a[i].x--;
41                     if(b[a[i].x]==0&&a[i].x>=1)
42                     {b[a[i].x]=1;d=1;break;}
43                     if(a[i].x<1)
44                         break;
45                 }
46                 if(d==0)
47                     sum+=a[i].y;
48             }
49         }
50         printf("%d
",sum);
51     }
52     return 0;
53 }

Brave Game HDU 1846

这道博弈题还是好找规律的:

巴什博弈:一个人拿1~m个,那谁面对m+1的局势的的时候则必败,很明显,先拿的就是要造这个局势,如果n是(m+1)*r+s(k为任意,s<m+1),那么很明显先拿的拿掉s后,然后无论下一个拿多少你都可以保证你拿完后都是拿了m+1个,这样后拿的必定面对必败局势,比如23 2,23=(3×7)+2;那我第一次拿掉2,然后无论每次第二个拿几我都可以使得这轮总共拿3,然后他必定会面对3这个局势,然后我就必胜,那什么时候必败呢,很明显如果我面对的是(m+1)的倍数的局势就必败。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int t,n,m;
 8     scanf("%d",&t);
 9     while(t--)
10     {
11         scanf("%d%d",&n,&m);
12             if(n%(m+1)==0)
13             printf("second
");
14         else
15             printf("first
");
16     }
17     return 0;
18 }

取石子游戏  HDU 1527

这个就根本做不出来的!!!!(因为他用了黄金分割)

这思路不用掌握,因为太难了。记住就算了吧。。。

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 int main ()
 5 {
 6     int a,b,dif;
 7     double p=(sqrt((double)5)+1)/double(2);//黄金分割
 8     while(cin>>a>>b)
 9     {
10     dif=abs(a-b);//取差值
11     a=a<b?a:b;//取较小的值
12     if(a==(int)(p*dif))//判断是不是奇异局势
13       printf("0
");
14     else printf("1
");
15     }
16     return 0;
17 }

Sum  POJ 1844

数学题,画几个数据就明白了。题意重点:1,2,3......i,数字之间+,-都可

先发现给出n(1,2,3...),前n的和的值奇偶性由前n的和决定!

如:n=5,s=15,那么有题意,他取的值为:15,13,11,9...(为奇数)那么就清楚了。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int s,i,d;
 8     while(scanf("%d",&s)!=EOF)
 9     {
10         for(i=1;i<=1000;i++)
11         {
12             d=i*(i+1)/2;
13             if(d>=s&&(d%2)==(s%2))
14                 break;
15         }
16         printf("%d
",i);
17     }
18 }

A Walk Through the Forest  HDU 1142

这里考的重点还是记忆化搜索!

主要是一开始题目都没看懂,就不知道怎么进行Dfs()

如原题中:He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. (意思是:如果A到B有路,且B到家的距离要小于A到家的距离)(在已经知道最短路的情况下)

其实没看懂多少。。。不过代码讲得清楚,

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<string.h>
 5 using namespace std;
 6 int a[1005][1005],c[1005],d[1005],dp[1005],n;
 7 int max1=20000005;
 8 int dfs(int k)
 9 {
10     int i;
11     if(k==2)
12         return 1;
13     if(dp[k])
14         return dp[k];
15     for(i=1;i<=n;i++)
16         if(a[k][i]!=max1&&d[k]>d[i])//题意在这个地方
17     {
18         dp[k]+=dfs(i);
19     }
20     return dp[k];
21 }
22 int main()
23 {
24     int m,i,j,a1,a2,a3,min1,p;
25     while(scanf("%d",&n)!=EOF)
26     {
27         if(n==0)
28             break;
29         scanf("%d",&m);
30         for(i=1;i<=n;i++)
31             for(j=1;j<=n;j++)
32             a[i][j]=max1;
33         for(i=1;i<=n;i++)
34             a[i][i]=0;
35         while(m--)
36         {
37             scanf("%d%d%d",&a1,&a2,&a3);
38             if(a[a1][a2]>a3)
39             {
40                 a[a1][a2]=a3;
41                 a[a2][a1]=a3;
42             }
43         }
44         memset(c,0,sizeof(c));
45         for(i=1;i<=n;i++)
46             d[i]=a[2][i];//先从终点找最短路
47         for(i=1;i<=n;i++)
48         {
49             min1=max1;
50             for(j=1;j<=n;j++)
51                 if(d[j]<min1&&!c[j])
52             {
53                 min1=d[j];
54                 p=j;
55             }
56             if(min1==max1)
57                 break;
58             c[p]=1;
59             for(j=1;j<=n;j++)
60                 if(d[j]>d[p]+a[p][j]&&!c[j])
61                     d[j]=d[p]+a[p][j];
62         }
63         memset(dp,0,sizeof(dp));
64         printf("%d
",dfs(1));//再从起点找路径数
65     }
66 }
原文地址:https://www.cnblogs.com/tt123/p/3259744.html